summaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/ARCMigrate/ARCMT.h10
-rw-r--r--include/clang/ARCMigrate/ARCMTActions.h2
-rw-r--r--include/clang/AST/APValue.h80
-rw-r--r--include/clang/AST/ASTConsumer.h22
-rw-r--r--include/clang/AST/ASTContext.h623
-rw-r--r--include/clang/AST/ASTDiagnostic.h2
-rw-r--r--include/clang/AST/ASTFwd.h2
-rw-r--r--include/clang/AST/ASTImporter.h165
-rw-r--r--include/clang/AST/ASTLambda.h2
-rw-r--r--include/clang/AST/ASTMutationListener.h44
-rw-r--r--include/clang/AST/ASTStructuralEquivalence.h34
-rw-r--r--include/clang/AST/ASTTypeTraits.h70
-rw-r--r--include/clang/AST/ASTUnresolvedSet.h4
-rw-r--r--include/clang/AST/Attr.h163
-rw-r--r--include/clang/AST/Availability.h4
-rw-r--r--include/clang/AST/BuiltinTypes.def77
-rw-r--r--include/clang/AST/CXXInheritance.h89
-rw-r--r--include/clang/AST/CanonicalType.h68
-rw-r--r--include/clang/AST/Comment.h2
-rw-r--r--include/clang/AST/CommentBriefParser.h2
-rw-r--r--include/clang/AST/CommentCommandTraits.h22
-rw-r--r--include/clang/AST/CommentLexer.h27
-rw-r--r--include/clang/AST/CommentSema.h4
-rw-r--r--include/clang/AST/ComparisonCategories.h243
-rw-r--r--include/clang/AST/DataCollection.h4
-rw-r--r--include/clang/AST/Decl.h964
-rw-r--r--include/clang/AST/DeclBase.h241
-rw-r--r--include/clang/AST/DeclCXX.h876
-rw-r--r--include/clang/AST/DeclContextInternals.h10
-rw-r--r--include/clang/AST/DeclFriend.h8
-rw-r--r--include/clang/AST/DeclLookups.h23
-rw-r--r--include/clang/AST/DeclObjC.h166
-rw-r--r--include/clang/AST/DeclOpenMP.h33
-rw-r--r--include/clang/AST/DeclTemplate.h537
-rw-r--r--include/clang/AST/DeclVisitor.h6
-rw-r--r--include/clang/AST/DeclarationName.h8
-rw-r--r--include/clang/AST/EvaluatedExprVisitor.h4
-rw-r--r--include/clang/AST/Expr.h526
-rw-r--r--include/clang/AST/ExprCXX.h651
-rw-r--r--include/clang/AST/ExprObjC.h136
-rw-r--r--include/clang/AST/ExprOpenMP.h18
-rw-r--r--include/clang/AST/ExternalASTMerger.h2
-rw-r--r--include/clang/AST/ExternalASTSource.h89
-rw-r--r--include/clang/AST/LambdaCapture.h32
-rw-r--r--include/clang/AST/LocInfoType.h2
-rw-r--r--include/clang/AST/Mangle.h8
-rw-r--r--include/clang/AST/MangleNumberingContext.h10
-rw-r--r--include/clang/AST/NSAPI.h66
-rw-r--r--include/clang/AST/NestedNameSpecifier.h142
-rw-r--r--include/clang/AST/NonTrivialTypeVisitor.h113
-rw-r--r--include/clang/AST/ODRHash.h15
-rw-r--r--include/clang/AST/OpenMPClause.h987
-rw-r--r--include/clang/AST/OperationKinds.def36
-rw-r--r--include/clang/AST/OperationKinds.h8
-rw-r--r--include/clang/AST/ParentMap.h2
-rw-r--r--include/clang/AST/PrettyDeclStackTrace.h (renamed from include/clang/Sema/PrettyDeclStackTrace.h)12
-rw-r--r--include/clang/AST/PrettyPrinter.h2
-rw-r--r--include/clang/AST/QualTypeNames.h5
-rw-r--r--include/clang/AST/RawCommentList.h54
-rw-r--r--include/clang/AST/RecordLayout.h2
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h65
-rw-r--r--include/clang/AST/Redeclarable.h102
-rw-r--r--include/clang/AST/SelectorLocationsKind.h16
-rw-r--r--include/clang/AST/Stmt.h198
-rw-r--r--include/clang/AST/StmtCXX.h43
-rw-r--r--include/clang/AST/StmtObjC.h32
-rw-r--r--include/clang/AST/StmtOpenMP.h580
-rw-r--r--include/clang/AST/StmtVisitor.h2
-rw-r--r--include/clang/AST/TemplateBase.h108
-rw-r--r--include/clang/AST/TemplateName.h102
-rw-r--r--include/clang/AST/Type.h639
-rw-r--r--include/clang/AST/TypeLoc.h113
-rw-r--r--include/clang/AST/TypeNodes.def1
-rw-r--r--include/clang/AST/TypeOrdering.h6
-rw-r--r--include/clang/AST/TypeVisitor.h6
-rw-r--r--include/clang/AST/UnresolvedSet.h4
-rw-r--r--include/clang/AST/VTTBuilder.h36
-rw-r--r--include/clang/AST/VTableBuilder.h102
-rw-r--r--include/clang/ASTMatchers/ASTMatchFinder.h48
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h1138
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h256
-rw-r--r--include/clang/ASTMatchers/ASTMatchersMacros.h27
-rw-r--r--include/clang/ASTMatchers/Dynamic/Diagnostics.h34
-rw-r--r--include/clang/ASTMatchers/Dynamic/Parser.h22
-rw-r--r--include/clang/ASTMatchers/Dynamic/Registry.h18
-rw-r--r--include/clang/ASTMatchers/Dynamic/VariantValue.h72
-rw-r--r--include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h12
-rw-r--r--include/clang/Analysis/Analyses/Consumed.h109
-rw-r--r--include/clang/Analysis/Analyses/Dominators.h91
-rw-r--r--include/clang/Analysis/Analyses/FormatString.h39
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h9
-rw-r--r--include/clang/Analysis/Analyses/PostOrderCFGView.h54
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafety.h63
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyCommon.h185
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyLogical.h4
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTIL.h543
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTraverse.h173
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyUtil.h107
-rw-r--r--include/clang/Analysis/Analyses/UninitializedValues.h26
-rw-r--r--include/clang/Analysis/AnalysisDeclContext.h104
-rw-r--r--include/clang/Analysis/CFG.h187
-rw-r--r--include/clang/Analysis/CallGraph.h20
-rw-r--r--include/clang/Analysis/CloneDetection.h6
-rw-r--r--include/clang/Analysis/CodeInjector.h4
-rw-r--r--include/clang/Analysis/ConstructionContext.h474
-rw-r--r--include/clang/Analysis/ProgramPoint.h89
-rw-r--r--include/clang/Basic/ABI.h40
-rw-r--r--include/clang/Basic/AddressSpaces.h18
-rw-r--r--include/clang/Basic/AlignedAllocation.h12
-rw-r--r--include/clang/Basic/AllDiagnostics.h2
-rw-r--r--include/clang/Basic/Attr.td416
-rw-r--r--include/clang/Basic/AttrDocs.td307
-rw-r--r--include/clang/Basic/AttrKinds.h4
-rw-r--r--include/clang/Basic/AttrSubjectMatchRules.h2
-rw-r--r--include/clang/Basic/Attributes.h2
-rw-r--r--include/clang/Basic/BitmaskEnum.h25
-rw-r--r--include/clang/Basic/Builtins.def73
-rw-r--r--include/clang/Basic/Builtins.h75
-rw-r--r--include/clang/Basic/BuiltinsAArch64.def35
-rw-r--r--include/clang/Basic/BuiltinsAMDGPU.def21
-rw-r--r--include/clang/Basic/BuiltinsHexagon.def45
-rw-r--r--include/clang/Basic/BuiltinsNEON.def1
-rw-r--r--include/clang/Basic/BuiltinsNVPTX.def318
-rw-r--r--include/clang/Basic/BuiltinsPPC.def9
-rw-r--r--include/clang/Basic/BuiltinsWebAssembly.def15
-rw-r--r--include/clang/Basic/BuiltinsX86.def3474
-rw-r--r--include/clang/Basic/BuiltinsX86_64.def104
-rw-r--r--include/clang/Basic/CMakeLists.txt4
-rw-r--r--include/clang/Basic/CapturedStmt.h3
-rw-r--r--include/clang/Basic/CharInfo.h13
-rw-r--r--include/clang/Basic/CommentOptions.h24
-rw-r--r--include/clang/Basic/Cuda.h21
-rw-r--r--include/clang/Basic/DebugInfoOptions.h2
-rw-r--r--include/clang/Basic/Diagnostic.h500
-rw-r--r--include/clang/Basic/Diagnostic.td9
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td16
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td63
-rw-r--r--include/clang/Basic/DiagnosticError.h2
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td7
-rw-r--r--include/clang/Basic/DiagnosticGroups.td63
-rw-r--r--include/clang/Basic/DiagnosticIDs.h62
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td26
-rw-r--r--include/clang/Basic/DiagnosticOptions.h25
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td43
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td876
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td83
-rw-r--r--include/clang/Basic/ExceptionSpecificationType.h17
-rw-r--r--include/clang/Basic/ExpressionTraits.h2
-rw-r--r--include/clang/Basic/Features.def238
-rw-r--r--include/clang/Basic/FileManager.h62
-rw-r--r--include/clang/Basic/FileSystemOptions.h6
-rw-r--r--include/clang/Basic/FileSystemStatCache.h69
-rw-r--r--include/clang/Basic/IdentifierTable.h136
-rw-r--r--include/clang/Basic/LLVM.h14
-rw-r--r--include/clang/Basic/Lambda.h6
-rw-r--r--include/clang/Basic/LangOptions.def35
-rw-r--r--include/clang/Basic/LangOptions.h139
-rw-r--r--include/clang/Basic/Linkage.h35
-rw-r--r--include/clang/Basic/MacroBuilder.h2
-rw-r--r--include/clang/Basic/Module.h238
-rw-r--r--include/clang/Basic/ObjCRuntime.h66
-rw-r--r--include/clang/Basic/OpenCLExtensions.def3
-rw-r--r--include/clang/Basic/OpenCLOptions.h6
-rw-r--r--include/clang/Basic/OpenMPKinds.def2
-rw-r--r--include/clang/Basic/OpenMPKinds.h46
-rw-r--r--include/clang/Basic/OperatorKinds.h6
-rw-r--r--include/clang/Basic/OperatorPrecedence.h4
-rw-r--r--include/clang/Basic/PartialDiagnostic.h96
-rw-r--r--include/clang/Basic/PlistSupport.h19
-rw-r--r--include/clang/Basic/PrettyStackTrace.h2
-rw-r--r--include/clang/Basic/Sanitizers.def12
-rw-r--r--include/clang/Basic/Sanitizers.h28
-rw-r--r--include/clang/Basic/SourceLocation.h127
-rw-r--r--include/clang/Basic/SourceManager.h454
-rw-r--r--include/clang/Basic/SourceManagerInternals.h22
-rw-r--r--include/clang/Basic/Specifiers.h55
-rw-r--r--include/clang/Basic/Stack.h27
-rw-r--r--include/clang/Basic/StmtNodes.td1
-rw-r--r--include/clang/Basic/SyncScope.h20
-rw-r--r--include/clang/Basic/TargetBuiltins.h30
-rw-r--r--include/clang/Basic/TargetCXXABI.h27
-rw-r--r--include/clang/Basic/TargetInfo.h412
-rw-r--r--include/clang/Basic/TargetOptions.h15
-rw-r--r--include/clang/Basic/TemplateKinds.h4
-rw-r--r--include/clang/Basic/TokenKinds.def62
-rw-r--r--include/clang/Basic/TokenKinds.h24
-rw-r--r--include/clang/Basic/TypeTraits.h11
-rw-r--r--include/clang/Basic/Version.h18
-rw-r--r--include/clang/Basic/VersionTuple.h168
-rw-r--r--include/clang/Basic/VirtualFileSystem.h125
-rw-r--r--include/clang/Basic/Visibility.h6
-rw-r--r--include/clang/Basic/X86Target.def147
-rw-r--r--include/clang/Basic/XRayInstr.h70
-rw-r--r--include/clang/Basic/XRayLists.h3
-rw-r--r--include/clang/Basic/arm_fp16.td131
-rw-r--r--include/clang/Basic/arm_neon.td524
-rw-r--r--include/clang/Basic/arm_neon_incl.td316
-rw-r--r--include/clang/CodeGen/BackendUtil.h2
-rw-r--r--include/clang/CodeGen/CGFunctionInfo.h73
-rw-r--r--include/clang/CodeGen/ConstantInitBuilder.h4
-rw-r--r--include/clang/CodeGen/SwiftCallingConv.h22
-rw-r--r--include/clang/Config/config.h.cmake13
-rw-r--r--include/clang/CrossTU/CrossTranslationUnit.h14
-rw-r--r--include/clang/Driver/Action.h113
-rw-r--r--include/clang/Driver/CC1Options.td31
-rw-r--r--include/clang/Driver/CLCompatOptions.td17
-rw-r--r--include/clang/Driver/Compilation.h61
-rw-r--r--include/clang/Driver/Distro.h3
-rw-r--r--include/clang/Driver/Driver.h93
-rw-r--r--include/clang/Driver/Job.h35
-rw-r--r--include/clang/Driver/Multilib.h54
-rw-r--r--include/clang/Driver/Options.td488
-rw-r--r--include/clang/Driver/SanitizerArgs.h2
-rw-r--r--include/clang/Driver/Tool.h8
-rw-r--r--include/clang/Driver/ToolChain.h136
-rw-r--r--include/clang/Driver/Types.def3
-rw-r--r--include/clang/Driver/Types.h3
-rw-r--r--include/clang/Driver/XRayArgs.h10
-rw-r--r--include/clang/Edit/Commit.h36
-rw-r--r--include/clang/Edit/EditedSource.h36
-rw-r--r--include/clang/Edit/EditsReceiver.h19
-rw-r--r--include/clang/Edit/FileOffset.h23
-rw-r--r--include/clang/Format/Format.h709
-rw-r--r--include/clang/Frontend/ASTConsumers.h7
-rw-r--r--include/clang/Frontend/ASTUnit.h286
-rw-r--r--include/clang/Frontend/ChainedDiagnosticConsumer.h2
-rw-r--r--include/clang/Frontend/CodeGenOptions.def54
-rw-r--r--include/clang/Frontend/CodeGenOptions.h34
-rw-r--r--include/clang/Frontend/CommandLineSourceLoc.h4
-rw-r--r--include/clang/Frontend/CompilerInstance.h53
-rw-r--r--include/clang/Frontend/CompilerInvocation.h78
-rw-r--r--include/clang/Frontend/DependencyOutputOptions.h25
-rw-r--r--include/clang/Frontend/DiagnosticRenderer.h32
-rw-r--r--include/clang/Frontend/FrontendAction.h48
-rw-r--r--include/clang/Frontend/FrontendActions.h32
-rw-r--r--include/clang/Frontend/FrontendOptions.h357
-rw-r--r--include/clang/Frontend/FrontendPluginRegistry.h12
-rw-r--r--include/clang/Frontend/LangStandards.def7
-rw-r--r--include/clang/Frontend/LayoutOverrideSource.h20
-rw-r--r--include/clang/Frontend/MultiplexConsumer.h23
-rw-r--r--include/clang/Frontend/PrecompiledPreamble.h27
-rw-r--r--include/clang/Frontend/SerializedDiagnosticPrinter.h6
-rw-r--r--include/clang/Frontend/SerializedDiagnosticReader.h83
-rw-r--r--include/clang/Frontend/SerializedDiagnostics.h8
-rw-r--r--include/clang/Frontend/TextDiagnostic.h6
-rw-r--r--include/clang/Frontend/TextDiagnosticBuffer.h32
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h2
-rw-r--r--include/clang/Frontend/Utils.h73
-rw-r--r--include/clang/Frontend/VerifyDiagnosticConsumer.h62
-rw-r--r--include/clang/FrontendTool/Utils.h9
-rw-r--r--include/clang/Index/IndexDataConsumer.h13
-rw-r--r--include/clang/Index/IndexSymbol.h48
-rw-r--r--include/clang/Index/IndexingAction.h25
-rw-r--r--include/clang/Index/USRGeneration.h18
-rw-r--r--include/clang/Lex/CodeCompletionHandler.h14
-rw-r--r--include/clang/Lex/DirectoryLookup.h12
-rw-r--r--include/clang/Lex/ExternalPreprocessorSource.h10
-rw-r--r--include/clang/Lex/HeaderSearch.h191
-rw-r--r--include/clang/Lex/HeaderSearchOptions.h28
-rw-r--r--include/clang/Lex/Lexer.h52
-rw-r--r--include/clang/Lex/LiteralSupport.h21
-rw-r--r--include/clang/Lex/MacroInfo.h118
-rw-r--r--include/clang/Lex/ModuleLoader.h20
-rw-r--r--include/clang/Lex/ModuleMap.h208
-rw-r--r--include/clang/Lex/MultipleIncludeOpt.h16
-rw-r--r--include/clang/Lex/PPCallbacks.h104
-rw-r--r--include/clang/Lex/PPConditionalDirectiveRecord.h10
-rw-r--r--include/clang/Lex/Pragma.h8
-rw-r--r--include/clang/Lex/PreprocessingRecord.h170
-rw-r--r--include/clang/Lex/Preprocessor.h392
-rw-r--r--include/clang/Lex/PreprocessorLexer.h30
-rw-r--r--include/clang/Lex/PreprocessorOptions.h52
-rw-r--r--include/clang/Lex/Token.h46
-rw-r--r--include/clang/Lex/TokenLexer.h14
-rw-r--r--include/clang/Lex/VariadicMacroSupport.h6
-rw-r--r--include/clang/Parse/ParseAST.h4
-rw-r--r--include/clang/Parse/Parser.h580
-rw-r--r--include/clang/Parse/RAIIObjectsForParser.h17
-rw-r--r--include/clang/Rewrite/Core/DeltaTree.h13
-rw-r--r--include/clang/Rewrite/Core/HTMLRewrite.h3
-rw-r--r--include/clang/Rewrite/Core/RewriteBuffer.h19
-rw-r--r--include/clang/Rewrite/Core/RewriteRope.h55
-rw-r--r--include/clang/Rewrite/Core/Rewriter.h56
-rw-r--r--include/clang/Rewrite/Core/TokenRewriter.h28
-rw-r--r--include/clang/Rewrite/Frontend/FixItRewriter.h69
-rw-r--r--include/clang/Rewrite/Frontend/FrontendActions.h2
-rw-r--r--include/clang/Sema/AnalysisBasedWarnings.h18
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h768
-rw-r--r--include/clang/Sema/CodeCompleteOptions.h11
-rw-r--r--include/clang/Sema/DeclSpec.h771
-rw-r--r--include/clang/Sema/DelayedDiagnostic.h87
-rw-r--r--include/clang/Sema/ExternalSemaSource.h38
-rw-r--r--include/clang/Sema/IdentifierResolver.h61
-rw-r--r--include/clang/Sema/Initialization.h767
-rw-r--r--include/clang/Sema/Lookup.h212
-rw-r--r--include/clang/Sema/LoopHint.h4
-rw-r--r--include/clang/Sema/MultiplexExternalSemaSource.h86
-rw-r--r--include/clang/Sema/ObjCMethodList.h6
-rw-r--r--include/clang/Sema/Overload.h298
-rw-r--r--include/clang/Sema/Ownership.h101
-rw-r--r--include/clang/Sema/ParsedAttr.h (renamed from include/clang/Sema/AttributeList.h)733
-rw-r--r--include/clang/Sema/ParsedTemplate.h53
-rw-r--r--include/clang/Sema/Scope.h100
-rw-r--r--include/clang/Sema/ScopeInfo.h521
-rw-r--r--include/clang/Sema/Sema.h1884
-rw-r--r--include/clang/Sema/SemaConsumer.h6
-rw-r--r--include/clang/Sema/SemaFixItUtils.h2
-rw-r--r--include/clang/Sema/SemaInternal.h55
-rw-r--r--include/clang/Sema/SemaLambda.h10
-rw-r--r--include/clang/Sema/Template.h197
-rw-r--r--include/clang/Sema/TemplateDeduction.h148
-rw-r--r--include/clang/Sema/TemplateInstCallback.h83
-rw-r--r--include/clang/Sema/TypoCorrection.h137
-rw-r--r--include/clang/Sema/Weak.h2
-rw-r--r--include/clang/Serialization/ASTBitCodes.h1104
-rw-r--r--include/clang/Serialization/ASTDeserializationListener.h18
-rw-r--r--include/clang/Serialization/ASTReader.h791
-rw-r--r--include/clang/Serialization/ASTWriter.h267
-rw-r--r--include/clang/Serialization/ContinuousRangeMap.h7
-rw-r--r--include/clang/Serialization/GlobalModuleIndex.h60
-rw-r--r--include/clang/Serialization/Module.h231
-rw-r--r--include/clang/Serialization/ModuleManager.h92
-rw-r--r--include/clang/StaticAnalyzer/Checkers/CMakeLists.txt1
-rw-r--r--include/clang/StaticAnalyzer/Checkers/Checkers.td50
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h236
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h246
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h181
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugType.h40
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h296
-rw-r--r--include/clang/StaticAnalyzer/Core/Checker.h24
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h294
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerRegistry.h22
-rw-r--r--include/clang/StaticAnalyzer/Core/IssueHash.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h6
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h30
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h79
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h296
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h42
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h21
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h41
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h174
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h8
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h28
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h39
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h125
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h264
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h29
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h274
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h185
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h142
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h216
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h77
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTContext.h31
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h62
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h996
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h91
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h64
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h232
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h5
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h73
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h25
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h10
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h39
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h140
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h31
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h11
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h18
-rw-r--r--include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h15
-rw-r--r--include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h10
-rw-r--r--include/clang/StaticAnalyzer/Frontend/FrontendActions.h2
-rw-r--r--include/clang/StaticAnalyzer/Frontend/ModelConsumer.h4
-rw-r--r--include/clang/Tooling/AllTUsExecution.h76
-rw-r--r--include/clang/Tooling/ArgumentsAdjusters.h27
-rw-r--r--include/clang/Tooling/CommonOptionsParser.h10
-rw-r--r--include/clang/Tooling/CompilationDatabase.h67
-rw-r--r--include/clang/Tooling/CompilationDatabasePluginRegistry.h14
-rw-r--r--include/clang/Tooling/Core/Diagnostic.h22
-rw-r--r--include/clang/Tooling/Core/Replacement.h88
-rw-r--r--include/clang/Tooling/DiagnosticsYaml.h6
-rw-r--r--include/clang/Tooling/Execution.h44
-rw-r--r--include/clang/Tooling/FileMatchTrie.h31
-rw-r--r--include/clang/Tooling/FixIt.h14
-rw-r--r--include/clang/Tooling/Inclusions/HeaderIncludes.h137
-rw-r--r--include/clang/Tooling/Inclusions/IncludeStyle.h139
-rw-r--r--include/clang/Tooling/JSONCompilationDatabase.h37
-rw-r--r--include/clang/Tooling/Refactoring.h12
-rw-r--r--include/clang/Tooling/Refactoring/AtomicChange.h34
-rw-r--r--include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h2
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringActionRule.h2
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringResultConsumer.h4
-rw-r--r--include/clang/Tooling/Refactoring/Rename/RenamingAction.h4
-rw-r--r--include/clang/Tooling/Refactoring/Rename/SymbolName.h2
-rw-r--r--include/clang/Tooling/Refactoring/Rename/USRFinder.h2
-rw-r--r--include/clang/Tooling/Refactoring/Rename/USRFindingAction.h2
-rw-r--r--include/clang/Tooling/Refactoring/Rename/USRLocFinder.h2
-rw-r--r--include/clang/Tooling/RefactoringCallbacks.h12
-rw-r--r--include/clang/Tooling/ReplacementsYaml.h8
-rw-r--r--include/clang/Tooling/StandaloneExecution.h11
-rw-r--r--include/clang/Tooling/ToolExecutorPluginRegistry.h8
-rw-r--r--include/clang/Tooling/Tooling.h163
-rw-r--r--include/clang/module.modulemap6
405 files changed, 27903 insertions, 18567 deletions
diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h
index 74081867eebc2..30c24f1cdb10e 100644
--- a/include/clang/ARCMigrate/ARCMT.h
+++ b/include/clang/ARCMigrate/ARCMT.h
@@ -22,7 +22,7 @@ namespace clang {
namespace arcmt {
class MigrationPass;
-/// \brief Creates an AST with the provided CompilerInvocation but with these
+/// Creates an AST with the provided CompilerInvocation but with these
/// changes:
/// -if a PCH/PTH is set, the original header is used instead
/// -Automatic Reference Counting mode is enabled
@@ -45,7 +45,7 @@ checkForManualIssues(CompilerInvocation &CI, const FrontendInputFile &Input,
bool emitPremigrationARCErrors = false,
StringRef plistOut = StringRef());
-/// \brief Works similar to checkForManualIssues but instead of checking, it
+/// Works similar to checkForManualIssues but instead of checking, it
/// applies automatic modifications to source files to conform to ARC.
///
/// \returns false if no error is produced, true otherwise.
@@ -55,7 +55,7 @@ applyTransformations(CompilerInvocation &origCI,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
DiagnosticConsumer *DiagClient);
-/// \brief Applies automatic modifications and produces temporary files
+/// Applies automatic modifications and produces temporary files
/// and metadata into the \p outputDir path.
///
/// \param emitPremigrationARCErrors if true all ARC errors will get emitted
@@ -72,7 +72,7 @@ bool migrateWithTemporaryFiles(
DiagnosticConsumer *DiagClient, StringRef outputDir,
bool emitPremigrationARCErrors, StringRef plistOut);
-/// \brief Get the set of file remappings from the \p outputDir path that
+/// Get the set of file remappings from the \p outputDir path that
/// migrateWithTemporaryFiles produced.
///
/// \returns false if no error is produced, true otherwise.
@@ -80,7 +80,7 @@ bool getFileRemappings(std::vector<std::pair<std::string,std::string> > &remap,
StringRef outputDir,
DiagnosticConsumer *DiagClient);
-/// \brief Get the set of file remappings from a list of files with remapping
+/// Get the set of file remappings from a list of files with remapping
/// info.
///
/// \returns false if no error is produced, true otherwise.
diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h
index 554e0c0c6d028..2571ca75be515 100644
--- a/include/clang/ARCMigrate/ARCMTActions.h
+++ b/include/clang/ARCMigrate/ARCMTActions.h
@@ -55,7 +55,7 @@ public:
bool emitPremigrationARCErrors);
};
-/// \brief Migrates to modern ObjC syntax.
+/// Migrates to modern ObjC syntax.
class ObjCMigrateAction : public WrapperFrontendAction {
std::string MigrateDir;
unsigned ObjCMigAction;
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index 7c431f3be8c4c..d4057c9da5f38 100644
--- a/include/clang/AST/APValue.h
+++ b/include/clang/AST/APValue.h
@@ -53,7 +53,58 @@ public:
MemberPointer,
AddrLabelDiff
};
- typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase;
+
+ class LValueBase {
+ public:
+ typedef llvm::PointerUnion<const ValueDecl *, const Expr *> PtrTy;
+
+ LValueBase() : CallIndex(0), Version(0) {}
+
+ template <class T>
+ LValueBase(T P, unsigned I = 0, unsigned V = 0)
+ : Ptr(P), CallIndex(I), Version(V) {}
+
+ template <class T>
+ bool is() const { return Ptr.is<T>(); }
+
+ template <class T>
+ T get() const { return Ptr.get<T>(); }
+
+ template <class T>
+ T dyn_cast() const { return Ptr.dyn_cast<T>(); }
+
+ void *getOpaqueValue() const;
+
+ bool isNull() const;
+
+ explicit operator bool () const;
+
+ PtrTy getPointer() const {
+ return Ptr;
+ }
+
+ unsigned getCallIndex() const {
+ return CallIndex;
+ }
+
+ void setCallIndex(unsigned Index) {
+ CallIndex = Index;
+ }
+
+ unsigned getVersion() const {
+ return Version;
+ }
+
+ bool operator==(const LValueBase &Other) const {
+ return Ptr == Other.Ptr && CallIndex == Other.CallIndex &&
+ Version == Other.Version;
+ }
+
+ private:
+ PtrTy Ptr;
+ unsigned CallIndex, Version;
+ };
+
typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
union LValuePathEntry {
/// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
@@ -135,15 +186,15 @@ public:
}
APValue(const APValue &RHS);
APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
- APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex,
+ APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
bool IsNullPtr = false)
: Kind(Uninitialized) {
- MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr);
+ MakeLValue(); setLValue(B, O, N, IsNullPtr);
}
APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
- bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false)
+ bool OnePastTheEnd, bool IsNullPtr = false)
: Kind(Uninitialized) {
- MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr);
+ MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
}
APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
MakeArray(InitElts, Size);
@@ -168,14 +219,14 @@ public:
MakeUninit();
}
- /// \brief Returns whether the object performed allocations.
+ /// Returns whether the object performed allocations.
///
/// If APValues are constructed via placement new, \c needsCleanup()
/// indicates whether the destructor must be called in order to correctly
/// free all allocated memory.
bool needsCleanup() const;
- /// \brief Swaps the contents of this and the given APValue.
+ /// Swaps the contents of this and the given APValue.
void swap(APValue &RHS);
ValueKind getKind() const { return Kind; }
@@ -255,6 +306,7 @@ public:
bool hasLValuePath() const;
ArrayRef<LValuePathEntry> getLValuePath() const;
unsigned getLValueCallIndex() const;
+ unsigned getLValueVersion() const;
bool isNullPointer() const;
APValue &getVectorElt(unsigned I) {
@@ -376,10 +428,10 @@ public:
((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
}
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
- unsigned CallIndex, bool IsNullPtr);
+ bool IsNullPtr);
void setLValue(LValueBase B, const CharUnits &O,
ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
- unsigned CallIndex, bool IsNullPtr);
+ bool IsNullPtr);
void setUnion(const FieldDecl *Field, const APValue &Value) {
assert(isUnion() && "Invalid accessor");
((UnionData*)(char*)Data.buffer)->Field = Field;
@@ -451,4 +503,14 @@ private:
} // end namespace clang.
+namespace llvm {
+template<> struct DenseMapInfo<clang::APValue::LValueBase> {
+ static clang::APValue::LValueBase getEmptyKey();
+ static clang::APValue::LValueBase getTombstoneKey();
+ static unsigned getHashValue(const clang::APValue::LValueBase &Base);
+ static bool isEqual(const clang::APValue::LValueBase &LHS,
+ const clang::APValue::LValueBase &RHS);
+};
+}
+
#endif
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index ad368c86c79c8..1167c566a35f3 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -32,7 +32,7 @@ namespace clang {
/// clients that read ASTs. This abstraction layer allows the client to be
/// independent of the AST producer (e.g. parser vs AST dump file reader, etc).
class ASTConsumer {
- /// \brief Whether this AST consumer also requires information about
+ /// Whether this AST consumer also requires information about
/// semantic analysis.
bool SemaConsumer;
@@ -53,7 +53,7 @@ public:
/// \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 or friend)
+ /// This callback is invoked each time an inline (method or friend)
/// function definition in a class is completed.
virtual void HandleInlineFunctionDefinition(FunctionDecl *D) {}
@@ -72,22 +72,22 @@ public:
/// can be defined in declspecs).
virtual void HandleTagDeclDefinition(TagDecl *D) {}
- /// \brief This callback is invoked the first time each TagDecl is required to
+ /// This callback is invoked the first time each TagDecl is required to
/// be complete.
virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {}
- /// \brief Invoked when a function is implicitly instantiated.
+ /// Invoked when a function is implicitly instantiated.
/// Note that at this point point it does not have a body, its body is
/// instantiated at the end of the translation unit and passed to
/// HandleTopLevelDecl.
virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {}
- /// \brief Handle the specified top-level declaration that occurred inside
+ /// Handle the specified top-level declaration that occurred inside
/// and ObjC container.
/// The default implementation ignored them.
virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
- /// \brief Handle an ImportDecl that was implicitly created due to an
+ /// Handle an ImportDecl that was implicitly created due to an
/// inclusion directive.
/// The default implementation passes it to HandleTopLevelDecl.
virtual void HandleImplicitImportDecl(ImportDecl *D);
@@ -103,7 +103,7 @@ public:
/// modified by the introduction of an implicit zero initializer.
virtual void CompleteTentativeDefinition(VarDecl *D) {}
- /// \brief Callback invoked when an MSInheritanceAttr has been attached to a
+ /// Callback invoked when an MSInheritanceAttr has been attached to a
/// CXXRecordDecl.
virtual void AssignInheritanceModel(CXXRecordDecl *RD) {}
@@ -111,19 +111,19 @@ public:
// variable has been instantiated.
virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {}
- /// \brief Callback involved at the end of a translation unit to
+ /// Callback involved at the end of a translation unit to
/// notify the consumer that a vtable for the given C++ class is
/// required.
///
/// \param RD The class whose vtable was used.
virtual void HandleVTable(CXXRecordDecl *RD) {}
- /// \brief If the consumer is interested in entities getting modified after
+ /// 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 nullptr; }
- /// \brief If the consumer is interested in entities being deserialized from
+ /// 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 nullptr;
@@ -132,7 +132,7 @@ public:
/// PrintStats - If desired, print any statistics.
virtual void PrintStats() {}
- /// \brief This callback is called for each function if the Parser was
+ /// This callback is called for each function if the Parser was
/// initialized with \c SkipFunctionBodies set to \c true.
///
/// \return \c true if the function's body should be skipped. The function
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index a5d080035df00..c6f8e2973e8e7 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Defines the clang::ASTContext interface.
+/// Defines the clang::ASTContext interface.
//
//===----------------------------------------------------------------------===//
@@ -18,6 +18,7 @@
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
+#include "clang/AST/ComparisonCategories.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
@@ -144,7 +145,7 @@ struct TypeInfo {
: Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
};
-/// \brief Holds long-lived AST nodes (such as types and decls) that can be
+/// Holds long-lived AST nodes (such as types and decls) that can be
/// referred to throughout the semantic analysis of a file.
class ASTContext : public RefCountedBase<ASTContext> {
friend class NestedNameSpecifier;
@@ -167,6 +168,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<DependentAddressSpaceType>
DependentAddressSpaceTypes;
mutable llvm::FoldingSet<VectorType> VectorTypes;
+ mutable llvm::FoldingSet<DependentVectorType> DependentVectorTypes;
mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
FunctionProtoTypes;
@@ -206,13 +208,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
ASTContext&>
SubstTemplateTemplateParmPacks;
- /// \brief The set of nested name specifiers.
+ /// The set of nested name specifiers.
///
/// This set is managed by the NestedNameSpecifier class.
mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
mutable NestedNameSpecifier *GlobalNestedNameSpecifier = nullptr;
- /// \brief A cache mapping from RecordDecls to ASTRecordLayouts.
+ /// A cache mapping from RecordDecls to ASTRecordLayouts.
///
/// This is lazily created. This is intentionally not serialized.
mutable llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>
@@ -220,35 +222,35 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*>
ObjCLayouts;
- /// \brief A cache from types to size and alignment information.
+ /// A cache from types to size and alignment information.
using TypeInfoMap = llvm::DenseMap<const Type *, struct TypeInfo>;
mutable TypeInfoMap MemoizedTypeInfo;
- /// \brief A cache mapping from CXXRecordDecls to key functions.
+ /// A cache mapping from CXXRecordDecls to key functions.
llvm::DenseMap<const CXXRecordDecl*, LazyDeclPtr> KeyFunctions;
- /// \brief Mapping from ObjCContainers to their ObjCImplementations.
+ /// Mapping from ObjCContainers to their ObjCImplementations.
llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
- /// \brief Mapping from ObjCMethod to its duplicate declaration in the same
+ /// Mapping from ObjCMethod to its duplicate declaration in the same
/// interface.
llvm::DenseMap<const ObjCMethodDecl*,const ObjCMethodDecl*> ObjCMethodRedecls;
- /// \brief Mapping from __block VarDecls to their copy initialization expr.
+ /// Mapping from __block VarDecls to their copy initialization expr.
llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits;
- /// \brief Mapping from class scope functions specialization to their
+ /// Mapping from class scope functions specialization to their
/// template patterns.
llvm::DenseMap<const FunctionDecl*, FunctionDecl*>
ClassScopeSpecializationPattern;
- /// \brief Mapping from materialized temporaries with static storage duration
+ /// Mapping from materialized temporaries with static storage duration
/// that appear in constant initializers to their evaluated values. These are
/// allocated in a std::map because their address must be stable.
llvm::DenseMap<const MaterializeTemporaryExpr *, APValue *>
MaterializedTemporaryValues;
- /// \brief Representation of a "canonical" template template parameter that
+ /// Representation of a "canonical" template template parameter that
/// is used in canonical template names.
class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode {
TemplateTemplateParmDecl *Parm;
@@ -270,32 +272,32 @@ class ASTContext : public RefCountedBase<ASTContext> {
TemplateTemplateParmDecl *
getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;
- /// \brief The typedef for the __int128_t type.
+ /// The typedef for the __int128_t type.
mutable TypedefDecl *Int128Decl = nullptr;
- /// \brief The typedef for the __uint128_t type.
+ /// The typedef for the __uint128_t type.
mutable TypedefDecl *UInt128Decl = nullptr;
- /// \brief The typedef for the target specific predefined
+ /// The typedef for the target specific predefined
/// __builtin_va_list type.
mutable TypedefDecl *BuiltinVaListDecl = nullptr;
/// The typedef for the predefined \c __builtin_ms_va_list type.
mutable TypedefDecl *BuiltinMSVaListDecl = nullptr;
- /// \brief The typedef for the predefined \c id type.
+ /// The typedef for the predefined \c id type.
mutable TypedefDecl *ObjCIdDecl = nullptr;
- /// \brief The typedef for the predefined \c SEL type.
+ /// The typedef for the predefined \c SEL type.
mutable TypedefDecl *ObjCSelDecl = nullptr;
- /// \brief The typedef for the predefined \c Class type.
+ /// The typedef for the predefined \c Class type.
mutable TypedefDecl *ObjCClassDecl = nullptr;
- /// \brief The typedef for the predefined \c Protocol class in Objective-C.
+ /// The typedef for the predefined \c Protocol class in Objective-C.
mutable ObjCInterfaceDecl *ObjCProtocolClassDecl = nullptr;
- /// \brief The typedef for the predefined 'BOOL' type.
+ /// The typedef for the predefined 'BOOL' type.
mutable TypedefDecl *BOOLDecl = nullptr;
// Typedefs which may be provided defining the structure of Objective-C
@@ -327,53 +329,53 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType ObjCNSStringType;
- /// \brief The typedef declaration for the Objective-C "instancetype" type.
+ /// The typedef declaration for the Objective-C "instancetype" type.
TypedefDecl *ObjCInstanceTypeDecl = nullptr;
- /// \brief The type for the C FILE type.
+ /// The type for the C FILE type.
TypeDecl *FILEDecl = nullptr;
- /// \brief The type for the C jmp_buf type.
+ /// The type for the C jmp_buf type.
TypeDecl *jmp_bufDecl = nullptr;
- /// \brief The type for the C sigjmp_buf type.
+ /// The type for the C sigjmp_buf type.
TypeDecl *sigjmp_bufDecl = nullptr;
- /// \brief The type for the C ucontext_t type.
+ /// The type for the C ucontext_t type.
TypeDecl *ucontext_tDecl = nullptr;
- /// \brief Type for the Block descriptor for Blocks CodeGen.
+ /// Type for the Block descriptor for Blocks CodeGen.
///
/// Since this is only used for generation of debug info, it is not
/// serialized.
mutable RecordDecl *BlockDescriptorType = nullptr;
- /// \brief Type for the Block descriptor for Blocks CodeGen.
+ /// Type for the Block descriptor for Blocks CodeGen.
///
/// Since this is only used for generation of debug info, it is not
/// serialized.
mutable RecordDecl *BlockDescriptorExtendedType = nullptr;
- /// \brief Declaration for the CUDA cudaConfigureCall function.
+ /// Declaration for the CUDA cudaConfigureCall function.
FunctionDecl *cudaConfigureCallDecl = nullptr;
- /// \brief Keeps track of all declaration attributes.
+ /// Keeps track of all declaration attributes.
///
/// Since so few decls have attrs, we keep them in a hash map instead of
/// wasting space in the Decl class.
llvm::DenseMap<const Decl*, AttrVec*> DeclAttrs;
- /// \brief A mapping from non-redeclarable declarations in modules that were
+ /// A mapping from non-redeclarable declarations in modules that were
/// merged with other declarations to the canonical declaration that they were
/// merged into.
llvm::DenseMap<Decl*, Decl*> MergedDecls;
- /// \brief A mapping from a defining declaration to a list of modules (other
+ /// A mapping from a defining declaration to a list of modules (other
/// than the owning module of the declaration) that contain merged
/// definitions of that entity.
llvm::DenseMap<NamedDecl*, llvm::TinyPtrVector<Module*>> MergedDefModules;
- /// \brief Initializers for a module, in order. Each Decl will be either
+ /// Initializers for a module, in order. Each Decl will be either
/// something that has a semantic effect on startup (such as a variable with
/// a non-constant initializer), or an ImportDecl (which recursively triggers
/// initialization of another module).
@@ -388,7 +390,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
ASTContext &this_() { return *this; }
public:
- /// \brief A type synonym for the TemplateOrInstantiation mapping.
+ /// A type synonym for the TemplateOrInstantiation mapping.
using TemplateOrSpecializationInfo =
llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>;
@@ -398,7 +400,7 @@ private:
friend class ASTWriter;
friend class CXXRecordDecl;
- /// \brief A mapping to contain the template or declaration that
+ /// A mapping to contain the template or declaration that
/// a variable declaration describes or was instantiated from,
/// respectively.
///
@@ -431,7 +433,7 @@ private:
llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>
TemplateOrInstantiation;
- /// \brief Keeps track of the declaration from which a using declaration was
+ /// Keeps track of the declaration from which a using declaration was
/// created during instantiation.
///
/// The source and target declarations are always a UsingDecl, an
@@ -461,7 +463,7 @@ private:
llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;
- /// \brief Mapping that stores the methods overridden by a given C++
+ /// Mapping that stores the methods overridden by a given C++
/// member function.
///
/// Since most C++ member functions aren't virtual and therefore
@@ -470,18 +472,18 @@ private:
using CXXMethodVector = llvm::TinyPtrVector<const CXXMethodDecl *>;
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
- /// \brief Mapping from each declaration context to its corresponding
+ /// Mapping from each declaration context to its corresponding
/// mangling numbering context (used for constructs like lambdas which
/// need to be consistently numbered for the mangler).
llvm::DenseMap<const DeclContext *, std::unique_ptr<MangleNumberingContext>>
MangleNumberingContexts;
- /// \brief Side-table of mangling numbers for declarations which rarely
+ /// Side-table of mangling numbers for declarations which rarely
/// need them (like static local vars).
llvm::MapVector<const NamedDecl *, unsigned> MangleNumbers;
llvm::MapVector<const VarDecl *, unsigned> StaticLocalNumbers;
- /// \brief Mapping that stores parameterIndex values for ParmVarDecls when
+ /// Mapping that stores parameterIndex values for ParmVarDecls when
/// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
using ParameterIndexTable = llvm::DenseMap<const VarDecl *, unsigned>;
ParameterIndexTable ParamIndices;
@@ -494,38 +496,38 @@ private:
mutable BuiltinTemplateDecl *MakeIntegerSeqDecl = nullptr;
mutable BuiltinTemplateDecl *TypePackElementDecl = nullptr;
- /// \brief The associated SourceManager object.
+ /// The associated SourceManager object.
SourceManager &SourceMgr;
- /// \brief The language options used to create the AST associated with
+ /// The language options used to create the AST associated with
/// this ASTContext object.
LangOptions &LangOpts;
- /// \brief Blacklist object that is used by sanitizers to decide which
+ /// Blacklist object that is used by sanitizers to decide which
/// entities should not be instrumented.
std::unique_ptr<SanitizerBlacklist> SanitizerBL;
- /// \brief Function filtering mechanism to determine whether a given function
+ /// Function filtering mechanism to determine whether a given function
/// should be imbued with the XRay "always" or "never" attributes.
std::unique_ptr<XRayFunctionFilter> XRayFilter;
- /// \brief The allocator used to create AST objects.
+ /// The allocator used to create AST objects.
///
/// AST objects are never destructed; rather, all memory associated with the
/// AST objects will be released when the ASTContext itself is destroyed.
mutable llvm::BumpPtrAllocator BumpAlloc;
- /// \brief Allocator for partial diagnostics.
+ /// Allocator for partial diagnostics.
PartialDiagnostic::StorageAllocator DiagAllocator;
- /// \brief The current C++ ABI.
+ /// The current C++ ABI.
std::unique_ptr<CXXABI> ABI;
CXXABI *createCXXABI(const TargetInfo &T);
- /// \brief The logical -> physical address space map.
+ /// The logical -> physical address space map.
const LangASMap *AddrSpaceMap = nullptr;
- /// \brief Address space map mangling must be used with language specific
+ /// Address space map mangling must be used with language specific
/// address spaces (e.g. OpenCL/CUDA)
bool AddrSpaceMapMangling;
@@ -541,10 +543,10 @@ public:
IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
ASTMutationListener *Listener = nullptr;
- /// \brief Contains parents of a node.
+ /// Contains parents of a node.
using ParentVector = llvm::SmallVector<ast_type_traits::DynTypedNode, 2>;
- /// \brief Maps from a node to its parents. This is used for nodes that have
+ /// Maps from a node to its parents. This is used for nodes that have
/// pointer identity only, which are more common and we can save space by
/// only storing a unique pointer to them.
using ParentMapPointers =
@@ -602,7 +604,7 @@ public:
}
};
- /// \brief Returns the parents of the given node.
+ /// Returns the parents of the given node.
///
/// Note that this will lazily compute the parents of all nodes
/// and store them for later retrieval. Thus, the first call is O(n)
@@ -701,10 +703,10 @@ public:
return FullSourceLoc(Loc,SourceMgr);
}
- /// \brief All comments in this translation unit.
+ /// All comments in this translation unit.
RawCommentList Comments;
- /// \brief True if comments are already loaded from ExternalASTSource.
+ /// True if comments are already loaded from ExternalASTSource.
mutable bool CommentsLoaded = false;
class RawCommentAndCacheFlags {
@@ -761,18 +763,18 @@ public:
const Decl *OriginalDecl;
};
- /// \brief Mapping from declarations to comments attached to any
+ /// Mapping from declarations to comments attached to any
/// redeclaration.
///
/// Raw comments are owned by Comments list. This mapping is populated
/// lazily.
mutable llvm::DenseMap<const Decl *, RawCommentAndCacheFlags> RedeclComments;
- /// \brief Mapping from declarations to parsed comments attached to any
+ /// Mapping from declarations to parsed comments attached to any
/// redeclaration.
mutable llvm::DenseMap<const Decl *, comments::FullComment *> ParsedComments;
- /// \brief Return the documentation comment attached to a given declaration,
+ /// Return the documentation comment attached to a given declaration,
/// without looking into cache.
RawComment *getRawCommentForDeclNoCache(const Decl *D) const;
@@ -784,10 +786,10 @@ public:
void addComment(const RawComment &RC) {
assert(LangOpts.RetainCommentsFromSystemHeaders ||
!SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin()));
- Comments.addComment(RC, BumpAlloc);
+ Comments.addComment(RC, LangOpts.CommentOpts, BumpAlloc);
}
- /// \brief Return the documentation comment attached to a given declaration.
+ /// Return the documentation comment attached to a given declaration.
/// Returns nullptr if no comment is attached.
///
/// \param OriginalDecl if not nullptr, is set to declaration AST node that
@@ -815,7 +817,7 @@ public:
private:
mutable comments::CommandTraits CommentCommandTraits;
- /// \brief Iterator that visits import declarations.
+ /// Iterator that visits import declarations.
class import_iterator {
ImportDecl *Import = nullptr;
@@ -857,13 +859,13 @@ public:
return CommentCommandTraits;
}
- /// \brief Retrieve the attributes for the given declaration.
+ /// Retrieve the attributes for the given declaration.
AttrVec& getDeclAttrs(const Decl *D);
- /// \brief Erase the attributes corresponding to the given declaration.
+ /// Erase the attributes corresponding to the given declaration.
void eraseDeclAttrs(const Decl *D);
- /// \brief If this variable is an instantiated static data member of a
+ /// If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
/// from which it was instantiated.
// FIXME: Remove ?
@@ -878,7 +880,7 @@ public:
void setClassScopeSpecializationPattern(FunctionDecl *FD,
FunctionDecl *Pattern);
- /// \brief Note that the static data member \p Inst is an instantiation of
+ /// Note that the static data member \p Inst is an instantiation of
/// the static data member template \p Tmpl of a class template.
void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
TemplateSpecializationKind TSK,
@@ -887,12 +889,12 @@ public:
void setTemplateOrSpecializationInfo(VarDecl *Inst,
TemplateOrSpecializationInfo TSI);
- /// \brief If the given using decl \p Inst is an instantiation of a
+ /// If the given using decl \p Inst is an instantiation of a
/// (possibly unresolved) using decl from a template instantiation,
/// return it.
NamedDecl *getInstantiatedFromUsingDecl(NamedDecl *Inst);
- /// \brief Remember that the using decl \p Inst is an instantiation
+ /// Remember that the using decl \p Inst is an instantiation
/// of the using decl \p Pattern of a class template.
void setInstantiatedFromUsingDecl(NamedDecl *Inst, NamedDecl *Pattern);
@@ -919,12 +921,12 @@ public:
overridden_method_range overridden_methods(const CXXMethodDecl *Method) const;
- /// \brief Note that the given C++ \p Method overrides the given \p
+ /// Note that the given C++ \p Method overrides the given \p
/// Overridden method.
void addOverriddenMethod(const CXXMethodDecl *Method,
const CXXMethodDecl *Overridden);
- /// \brief Return C++ or ObjC overridden methods for the given \p Method.
+ /// Return C++ or ObjC overridden methods for the given \p Method.
///
/// An ObjC method is considered to override any method in the class's
/// base classes, its protocols, or its categories' protocols, that has
@@ -935,7 +937,7 @@ public:
const NamedDecl *Method,
SmallVectorImpl<const NamedDecl *> &Overridden) const;
- /// \brief Notify the AST context that a new import declaration has been
+ /// Notify the AST context that a new import declaration has been
/// parsed or implicitly created within this translation unit.
void addedLocalImportDecl(ImportDecl *Import);
@@ -957,16 +959,16 @@ public:
MergedDecls[D] = Primary;
}
- /// \brief Note that the definition \p ND has been merged into module \p M,
+ /// Note that the definition \p ND has been merged into module \p M,
/// and should be visible whenever \p M is visible.
void mergeDefinitionIntoModule(NamedDecl *ND, Module *M,
bool NotifyListeners = true);
- /// \brief Clean up the merged definition list. Call this if you might have
+ /// Clean up the merged definition list. Call this if you might have
/// added duplicates into the list.
void deduplicateMergedDefinitonsFor(NamedDecl *ND);
- /// \brief Get the additional modules in which the definition \p Def has
+ /// Get the additional modules in which the definition \p Def has
/// been merged.
ArrayRef<Module*> getModulesWithMergedDefinition(const NamedDecl *Def) {
auto MergedIt = MergedDefModules.find(Def);
@@ -999,12 +1001,24 @@ public:
CanQualType WCharTy; // [C++ 3.9.1p5].
CanQualType WideCharTy; // Same as WCharTy in C++, integer type in C99.
CanQualType WIntTy; // [C99 7.24.1], integer type unchanged by default promotions.
+ CanQualType Char8Ty; // [C++20 proposal]
CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99.
CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99.
CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
+ CanQualType ShortAccumTy, AccumTy,
+ LongAccumTy; // ISO/IEC JTC1 SC22 WG14 N1169 Extension
+ CanQualType UnsignedShortAccumTy, UnsignedAccumTy, UnsignedLongAccumTy;
+ CanQualType ShortFractTy, FractTy, LongFractTy;
+ CanQualType UnsignedShortFractTy, UnsignedFractTy, UnsignedLongFractTy;
+ CanQualType SatShortAccumTy, SatAccumTy, SatLongAccumTy;
+ CanQualType SatUnsignedShortAccumTy, SatUnsignedAccumTy,
+ SatUnsignedLongAccumTy;
+ CanQualType SatShortFractTy, SatFractTy, SatLongFractTy;
+ CanQualType SatUnsignedShortFractTy, SatUnsignedFractTy,
+ SatUnsignedLongFractTy;
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
@@ -1036,20 +1050,20 @@ public:
ASTContext &operator=(const ASTContext &) = delete;
~ASTContext();
- /// \brief Attach an external AST source to the AST context.
+ /// Attach an external AST source to the AST context.
///
/// 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(IntrusiveRefCntPtr<ExternalASTSource> Source);
- /// \brief Retrieve a pointer to the external AST source associated
+ /// Retrieve a pointer to the external AST source associated
/// with this AST context, if any.
ExternalASTSource *getExternalSource() const {
return ExternalSource.get();
}
- /// \brief Attach an AST mutation listener to the AST context.
+ /// Attach an AST mutation listener to the AST context.
///
/// The AST mutation listener provides the ability to track modifications to
/// the abstract syntax tree entities committed after they were initially
@@ -1058,7 +1072,7 @@ public:
this->Listener = Listener;
}
- /// \brief Retrieve a pointer to the AST mutation listener associated
+ /// Retrieve a pointer to the AST mutation listener associated
/// with this AST context, if any.
ASTMutationListener *getASTMutationListener() const { return Listener; }
@@ -1068,18 +1082,18 @@ public:
BuiltinTemplateDecl *buildBuiltinTemplateDecl(BuiltinTemplateKind BTK,
const IdentifierInfo *II) const;
- /// \brief Create a new implicit TU-level CXXRecordDecl or RecordDecl
+ /// 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.
+ /// 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.
+ /// Retrieve the declaration for the 128-bit signed integer type.
TypedefDecl *getInt128Decl() const;
- /// \brief Retrieve the declaration for the 128-bit unsigned integer type.
+ /// Retrieve the declaration for the 128-bit unsigned integer type.
TypedefDecl *getUInt128Decl() const;
//===--------------------------------------------------------------------===//
@@ -1087,7 +1101,7 @@ public:
//===--------------------------------------------------------------------===//
private:
- /// \brief Return a type with extended qualifiers.
+ /// Return a type with extended qualifiers.
QualType getExtQualType(const Type *Base, Qualifiers Quals) const;
QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const;
@@ -1095,7 +1109,7 @@ private:
QualType getPipeType(QualType T, bool ReadOnly) const;
public:
- /// \brief Return the uniqued reference to the type for an address space
+ /// Return the uniqued reference to the type for an address space
/// qualified type with the specified type and address space.
///
/// The resulting type has a union of the qualifiers from T and the address
@@ -1103,29 +1117,29 @@ public:
/// replaced.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const;
- /// \brief Remove any existing address space on the type and returns the type
+ /// Remove any existing address space on the type and returns the type
/// with qualifiers intact (or that's the idea anyway)
///
/// The return type should be T with all prior qualifiers minus the address
/// space.
QualType removeAddrSpaceQualType(QualType T) const;
- /// \brief Apply Objective-C protocol qualifiers to the given type.
+ /// Apply Objective-C protocol qualifiers to the given type.
/// \param allowOnPointerType specifies if we can apply protocol
/// qualifiers on ObjCObjectPointerType. It can be set to true when
- /// contructing the canonical type of a Objective-C type parameter.
+ /// constructing the canonical type of a Objective-C type parameter.
QualType applyObjCProtocolQualifiers(QualType type,
ArrayRef<ObjCProtocolDecl *> protocols, bool &hasError,
bool allowOnPointerType = false) const;
- /// \brief Return the uniqued reference to the type for an Objective-C
+ /// Return the uniqued reference to the type for an Objective-C
/// gc-qualified type.
///
- /// The retulting type has a union of the qualifiers from T and the gc
+ /// The resulting type has a union of the qualifiers from T and the gc
/// attribute.
QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const;
- /// \brief Return the uniqued reference to the type for a \c restrict
+ /// Return the uniqued reference to the type for a \c restrict
/// qualified type.
///
/// The resulting type has a union of the qualifiers from \p T and
@@ -1134,7 +1148,7 @@ public:
return T.withFastQualifiers(Qualifiers::Restrict);
}
- /// \brief Return the uniqued reference to the type for a \c volatile
+ /// Return the uniqued reference to the type for a \c volatile
/// qualified type.
///
/// The resulting type has a union of the qualifiers from \p T and
@@ -1143,7 +1157,7 @@ public:
return T.withFastQualifiers(Qualifiers::Volatile);
}
- /// \brief Return the uniqued reference to the type for a \c const
+ /// Return the uniqued reference to the type for a \c const
/// qualified type.
///
/// The resulting type has a union of the qualifiers from \p T and \c const.
@@ -1152,41 +1166,48 @@ public:
/// calling T.withConst().
QualType getConstType(QualType T) const { return T.withConst(); }
- /// \brief Change the ExtInfo on a function type.
+ /// Change the ExtInfo on a function type.
const FunctionType *adjustFunctionType(const FunctionType *Fn,
FunctionType::ExtInfo EInfo);
/// Adjust the given function result type.
CanQualType getCanonicalFunctionResultType(QualType ResultType) const;
- /// \brief Change the result type of a function type once it is deduced.
+ /// Change the result type of a function type once it is deduced.
void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
- /// \brief Determine whether two function types are the same, ignoring
+ /// Get a function type and produce the equivalent function type with the
+ /// specified exception specification. Type sugar that can be present on a
+ /// declaration of a function with an exception specification is permitted
+ /// and preserved. Other type sugar (for instance, typedefs) is not.
+ QualType getFunctionTypeWithExceptionSpec(
+ QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI);
+
+ /// Determine whether two function types are the same, ignoring
/// exception specifications in cases where they're part of the type.
bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U);
- /// \brief Change the exception specification on a function once it is
+ /// Change the exception specification on a function once it is
/// delay-parsed, instantiated, or computed.
void adjustExceptionSpec(FunctionDecl *FD,
const FunctionProtoType::ExceptionSpecInfo &ESI,
bool AsWritten = false);
- /// \brief Return the uniqued reference to the type for a complex
+ /// Return the uniqued reference to the type for a complex
/// number with the specified element type.
QualType getComplexType(QualType T) const;
CanQualType getComplexType(CanQualType T) const {
return CanQualType::CreateUnsafe(getComplexType((QualType) T));
}
- /// \brief Return the uniqued reference to the type for a pointer to
+ /// Return the uniqued reference to the type for a pointer to
/// the specified type.
QualType getPointerType(QualType T) const;
CanQualType getPointerType(CanQualType T) const {
return CanQualType::CreateUnsafe(getPointerType((QualType) T));
}
- /// \brief Return the uniqued reference to a type adjusted from the original
+ /// 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 {
@@ -1194,7 +1215,7 @@ public:
getAdjustedType((QualType)Orig, (QualType)New));
}
- /// \brief Return the uniqued reference to the decayed version of the given
+ /// 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.
QualType getDecayedType(QualType T) const;
@@ -1202,11 +1223,11 @@ public:
return CanQualType::CreateUnsafe(getDecayedType((QualType) T));
}
- /// \brief Return the uniqued reference to the atomic type for the specified
+ /// Return the uniqued reference to the atomic type for the specified
/// type.
QualType getAtomicType(QualType T) const;
- /// \brief Return the uniqued reference to the type for a block of the
+ /// Return the uniqued reference to the type for a block of the
/// specified type.
QualType getBlockPointerType(QualType T) const;
@@ -1214,10 +1235,10 @@ public:
/// blocks.
QualType getBlockDescriptorType() const;
- /// \brief Return a read_only pipe type for the specified type.
+ /// Return a read_only pipe type for the specified type.
QualType getReadPipeType(QualType T) const;
- /// \brief Return a write_only pipe type for the specified type.
+ /// Return a write_only pipe type for the specified type.
QualType getWritePipeType(QualType T) const;
/// Gets the struct used to keep track of the extended descriptor for
@@ -1241,36 +1262,36 @@ public:
/// Returns true iff we need copy/dispose helpers for the given type.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D);
- /// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set
- /// to false in this case. If HasByrefExtendedLayout returns true, byref variable
- /// has extended lifetime.
+ /// Returns true, if given type has a known lifetime. HasByrefExtendedLayout
+ /// is set to false in this case. If HasByrefExtendedLayout returns true,
+ /// byref variable has extended lifetime.
bool getByrefLifetime(QualType Ty,
Qualifiers::ObjCLifetime &Lifetime,
bool &HasByrefExtendedLayout) const;
- /// \brief Return the uniqued reference to the type for an lvalue reference
+ /// Return the uniqued reference to the type for an lvalue reference
/// to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true)
const;
- /// \brief Return the uniqued reference to the type for an rvalue reference
+ /// Return the uniqued reference to the type for an rvalue reference
/// to the specified type.
QualType getRValueReferenceType(QualType T) const;
- /// \brief Return the uniqued reference to the type for a member pointer to
+ /// Return the uniqued reference to the type for a member pointer to
/// the specified type in the specified class.
///
/// The class \p Cls is a \c Type because it could be a dependent name.
QualType getMemberPointerType(QualType T, const Type *Cls) const;
- /// \brief Return a non-unique reference to the type for a variable array of
+ /// Return a non-unique reference to the type for a variable array of
/// the specified element type.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
ArrayType::ArraySizeModifier ASM,
unsigned IndexTypeQuals,
SourceRange Brackets) const;
- /// \brief Return a non-unique reference to the type for a dependently-sized
+ /// Return a non-unique reference to the type for a dependently-sized
/// array of the specified element type.
///
/// FIXME: We will need these to be uniqued, or at least comparable, at some
@@ -1280,29 +1301,34 @@ public:
unsigned IndexTypeQuals,
SourceRange Brackets) const;
- /// \brief Return a unique reference to the type for an incomplete array of
+ /// Return a unique reference to the type for an incomplete array of
/// the specified element type.
QualType getIncompleteArrayType(QualType EltTy,
ArrayType::ArraySizeModifier ASM,
unsigned IndexTypeQuals) const;
- /// \brief Return the unique reference to the type for a constant array of
+ /// Return the unique reference to the type for a constant array of
/// the specified element type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
ArrayType::ArraySizeModifier ASM,
unsigned IndexTypeQuals) const;
- /// \brief Returns a vla type where known sizes are replaced with [*].
+ /// Returns a vla type where known sizes are replaced with [*].
QualType getVariableArrayDecayedType(QualType Ty) const;
- /// \brief Return the unique reference to a vector type of the specified
+ /// Return the unique reference to a vector type of the specified
/// element type and size.
///
/// \pre \p VectorType must be a built-in type.
QualType getVectorType(QualType VectorType, unsigned NumElts,
VectorType::VectorKind VecKind) const;
+ /// Return the unique reference to the type for a dependently sized vector of
+ /// the specified element type.
+ QualType getDependentVectorType(QualType VectorType, Expr *SizeExpr,
+ SourceLocation AttrLoc,
+ VectorType::VectorKind VecKind) const;
- /// \brief Return the unique reference to an extended vector type
+ /// Return the unique reference to an extended vector type
/// of the specified element type and size.
///
/// \pre \p VectorType must be a built-in type.
@@ -1321,7 +1347,7 @@ public:
Expr *AddrSpaceExpr,
SourceLocation AttrLoc) const;
- /// \brief Return a K&R style C function type like 'int()'.
+ /// Return a K&R style C function type like 'int()'.
QualType getFunctionNoProtoType(QualType ResultTy,
const FunctionType::ExtInfo &Info) const;
@@ -1329,20 +1355,22 @@ public:
return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo());
}
- /// \brief Return a normal function type with a typed argument list.
+ /// Return a normal function type with a typed argument list.
QualType getFunctionType(QualType ResultTy, ArrayRef<QualType> Args,
const FunctionProtoType::ExtProtoInfo &EPI) const {
return getFunctionTypeInternal(ResultTy, Args, EPI, false);
}
+ QualType adjustStringLiteralBaseType(QualType StrLTy) const;
+
private:
- /// \brief Return a normal function type with a typed argument list.
+ /// Return a normal function type with a typed argument list.
QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef<QualType> Args,
const FunctionProtoType::ExtProtoInfo &EPI,
bool OnlyWantCanonical) const;
public:
- /// \brief Return the unique reference to the type for the specified type
+ /// Return the unique reference to the type for the specified type
/// declaration.
QualType getTypeDeclType(const TypeDecl *Decl,
const TypeDecl *PrevDecl = nullptr) const {
@@ -1358,7 +1386,7 @@ public:
return getTypeDeclTypeSlow(Decl);
}
- /// \brief Return the unique reference to the type for the specified
+ /// Return the unique reference to the type for the specified
/// typedef-name decl.
QualType getTypedefType(const TypedefNameDecl *Decl,
QualType Canon = QualType()) const;
@@ -1404,8 +1432,8 @@ public:
QualType getParenType(QualType NamedType) const;
QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- QualType NamedType) const;
+ NestedNameSpecifier *NNS, QualType NamedType,
+ TagDecl *OwnedTagDecl = nullptr) const;
QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
@@ -1455,105 +1483,105 @@ public:
bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
ObjCInterfaceDecl *IDecl);
- /// \brief Return a ObjCObjectPointerType type for the given ObjCObjectType.
+ /// Return a ObjCObjectPointerType type for the given ObjCObjectType.
QualType getObjCObjectPointerType(QualType OIT) const;
- /// \brief GCC extension.
+ /// GCC extension.
QualType getTypeOfExprType(Expr *e) const;
QualType getTypeOfType(QualType t) const;
- /// \brief C++11 decltype.
+ /// C++11 decltype.
QualType getDecltypeType(Expr *e, QualType UnderlyingType) const;
- /// \brief Unary type transforms
+ /// Unary type transforms
QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType,
UnaryTransformType::UTTKind UKind) const;
- /// \brief C++11 deduced auto type.
+ /// C++11 deduced auto type.
QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
bool IsDependent) const;
- /// \brief C++11 deduction pattern for 'auto' type.
+ /// C++11 deduction pattern for 'auto' type.
QualType getAutoDeductType() const;
- /// \brief C++11 deduction pattern for 'auto &&' type.
+ /// C++11 deduction pattern for 'auto &&' type.
QualType getAutoRRefDeductType() const;
- /// \brief C++17 deduced class template specialization type.
+ /// C++17 deduced class template specialization type.
QualType getDeducedTemplateSpecializationType(TemplateName Template,
QualType DeducedType,
bool IsDependent) const;
- /// \brief Return the unique reference to the type for the specified TagDecl
+ /// Return the unique reference to the type for the specified TagDecl
/// (struct/union/class/enum) decl.
QualType getTagDeclType(const TagDecl *Decl) const;
- /// \brief Return the unique type for "size_t" (C99 7.17), defined in
+ /// Return the unique type for "size_t" (C99 7.17), defined in
/// <stddef.h>.
///
/// The sizeof operator requires this (C99 6.5.3.4p4).
CanQualType getSizeType() const;
- /// \brief Return the unique signed counterpart of
+ /// Return the unique signed counterpart of
/// the integer type corresponding to size_t.
CanQualType getSignedSizeType() const;
- /// \brief Return the unique type for "intmax_t" (C99 7.18.1.5), defined in
+ /// Return the unique type for "intmax_t" (C99 7.18.1.5), defined in
/// <stdint.h>.
CanQualType getIntMaxType() const;
- /// \brief Return the unique type for "uintmax_t" (C99 7.18.1.5), defined in
+ /// Return the unique type for "uintmax_t" (C99 7.18.1.5), defined in
/// <stdint.h>.
CanQualType getUIntMaxType() const;
- /// \brief Return the unique wchar_t type available in C++ (and available as
+ /// Return the unique wchar_t type available in C++ (and available as
/// __wchar_t as a Microsoft extension).
QualType getWCharType() const { return WCharTy; }
- /// \brief Return the type of wide characters. In C++, this returns the
+ /// Return the type of wide characters. In C++, this returns the
/// unique wchar_t type. In C99, this returns a type compatible with the type
/// defined in <stddef.h> as defined by the target.
QualType getWideCharType() const { return WideCharTy; }
- /// \brief Return the type of "signed wchar_t".
+ /// Return the type of "signed wchar_t".
///
/// Used when in C++, as a GCC extension.
QualType getSignedWCharType() const;
- /// \brief Return the type of "unsigned wchar_t".
+ /// Return the type of "unsigned wchar_t".
///
/// Used when in C++, as a GCC extension.
QualType getUnsignedWCharType() const;
- /// \brief In C99, this returns a type compatible with the type
+ /// In C99, this returns a type compatible with the type
/// defined in <stddef.h> as defined by the target.
QualType getWIntType() const { return WIntTy; }
- /// \brief Return a type compatible with "intptr_t" (C99 7.18.1.4),
+ /// Return a type compatible with "intptr_t" (C99 7.18.1.4),
/// as defined by the target.
QualType getIntPtrType() const;
- /// \brief Return a type compatible with "uintptr_t" (C99 7.18.1.4),
+ /// Return a type compatible with "uintptr_t" (C99 7.18.1.4),
/// as defined by the target.
QualType getUIntPtrType() const;
- /// \brief Return the unique type for "ptrdiff_t" (C99 7.17) defined in
+ /// Return the unique type for "ptrdiff_t" (C99 7.17) defined in
/// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
QualType getPointerDiffType() const;
- /// \brief Return the unique unsigned counterpart of "ptrdiff_t"
+ /// Return the unique unsigned counterpart of "ptrdiff_t"
/// integer type. The standard (C11 7.21.6.1p7) refers to this type
/// in the definition of %tu format specifier.
QualType getUnsignedPointerDiffType() const;
- /// \brief Return the unique type for "pid_t" defined in
+ /// Return the unique type for "pid_t" defined in
/// <sys/types.h>. We need this to compute the correct type for vfork().
QualType getProcessIDType() const;
- /// \brief Return the C structure type used to represent constant CFStrings.
+ /// Return the C structure type used to represent constant CFStrings.
QualType getCFConstantStringType() const;
- /// \brief Returns the C struct type for objc_super
+ /// Returns the C struct type for objc_super
QualType getObjCSuperType() const;
void setObjCSuperType(QualType ST) { ObjCSuperType = ST; }
@@ -1582,7 +1610,7 @@ public:
ObjCNSStringType = T;
}
- /// \brief Retrieve the type that \c id has been defined to, which may be
+ /// Retrieve the type that \c id has been defined to, which may be
/// different from the built-in \c id if \c id has been typedef'd.
QualType getObjCIdRedefinitionType() const {
if (ObjCIdRedefinitionType.isNull())
@@ -1590,12 +1618,12 @@ public:
return ObjCIdRedefinitionType;
}
- /// \brief Set the user-written type that redefines \c id.
+ /// Set the user-written type that redefines \c id.
void setObjCIdRedefinitionType(QualType RedefType) {
ObjCIdRedefinitionType = RedefType;
}
- /// \brief Retrieve the type that \c Class has been defined to, which may be
+ /// Retrieve the type that \c Class has been defined to, which may be
/// different from the built-in \c Class if \c Class has been typedef'd.
QualType getObjCClassRedefinitionType() const {
if (ObjCClassRedefinitionType.isNull())
@@ -1603,12 +1631,12 @@ public:
return ObjCClassRedefinitionType;
}
- /// \brief Set the user-written type that redefines 'SEL'.
+ /// Set the user-written type that redefines 'SEL'.
void setObjCClassRedefinitionType(QualType RedefType) {
ObjCClassRedefinitionType = RedefType;
}
- /// \brief Retrieve the type that 'SEL' has been defined to, which may be
+ /// Retrieve the type that 'SEL' has been defined to, which may be
/// different from the built-in 'SEL' if 'SEL' has been typedef'd.
QualType getObjCSelRedefinitionType() const {
if (ObjCSelRedefinitionType.isNull())
@@ -1616,7 +1644,7 @@ public:
return ObjCSelRedefinitionType;
}
- /// \brief Set the user-written type that redefines 'SEL'.
+ /// Set the user-written type that redefines 'SEL'.
void setObjCSelRedefinitionType(QualType RedefType) {
ObjCSelRedefinitionType = RedefType;
}
@@ -1676,68 +1704,68 @@ public:
return TypePackElementName;
}
- /// \brief Retrieve the Objective-C "instancetype" type, if already known;
+ /// Retrieve the Objective-C "instancetype" type, if already known;
/// otherwise, returns a NULL type;
QualType getObjCInstanceType() {
return getTypeDeclType(getObjCInstanceTypeDecl());
}
- /// \brief Retrieve the typedef declaration corresponding to the Objective-C
+ /// Retrieve the typedef declaration corresponding to the Objective-C
/// "instancetype" type.
TypedefDecl *getObjCInstanceTypeDecl();
- /// \brief Set the type for the C FILE type.
+ /// Set the type for the C FILE type.
void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; }
- /// \brief Retrieve the C FILE type.
+ /// Retrieve the C FILE type.
QualType getFILEType() const {
if (FILEDecl)
return getTypeDeclType(FILEDecl);
return QualType();
}
- /// \brief Set the type for the C jmp_buf type.
+ /// Set the type for the C jmp_buf type.
void setjmp_bufDecl(TypeDecl *jmp_bufDecl) {
this->jmp_bufDecl = jmp_bufDecl;
}
- /// \brief Retrieve the C jmp_buf type.
+ /// Retrieve the C jmp_buf type.
QualType getjmp_bufType() const {
if (jmp_bufDecl)
return getTypeDeclType(jmp_bufDecl);
return QualType();
}
- /// \brief Set the type for the C sigjmp_buf type.
+ /// Set the type for the C sigjmp_buf type.
void setsigjmp_bufDecl(TypeDecl *sigjmp_bufDecl) {
this->sigjmp_bufDecl = sigjmp_bufDecl;
}
- /// \brief Retrieve the C sigjmp_buf type.
+ /// Retrieve the C sigjmp_buf type.
QualType getsigjmp_bufType() const {
if (sigjmp_bufDecl)
return getTypeDeclType(sigjmp_bufDecl);
return QualType();
}
- /// \brief Set the type for the C ucontext_t type.
+ /// Set the type for the C ucontext_t type.
void setucontext_tDecl(TypeDecl *ucontext_tDecl) {
this->ucontext_tDecl = ucontext_tDecl;
}
- /// \brief Retrieve the C ucontext_t type.
+ /// Retrieve the C ucontext_t type.
QualType getucontext_tType() const {
if (ucontext_tDecl)
return getTypeDeclType(ucontext_tDecl);
return QualType();
}
- /// \brief The result type of logical operations, '<', '>', '!=', etc.
+ /// The result type of logical operations, '<', '>', '!=', etc.
QualType getLogicalOperationType() const {
return getLangOpts().CPlusPlus ? BoolTy : IntTy;
}
- /// \brief Emit the Objective-CC type encoding for the given type \p T into
+ /// Emit the Objective-CC type encoding for the given type \p T into
/// \p S.
///
/// If \p Field is specified then record field names are also encoded.
@@ -1745,17 +1773,17 @@ public:
const FieldDecl *Field=nullptr,
QualType *NotEncodedT=nullptr) const;
- /// \brief Emit the Objective-C property type encoding for the given
+ /// 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;
- /// \brief Put the string version of the type qualifiers \p QT into \p S.
+ /// Put the string version of the type qualifiers \p QT into \p S.
void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
std::string &S) const;
- /// \brief Emit the encoded type for the function \p Decl into \p S.
+ /// Emit the encoded type for the function \p Decl into \p S.
///
/// This is in the same format as Objective-C method encodings.
///
@@ -1763,12 +1791,12 @@ public:
/// types is incomplete), false otherwise.
std::string getObjCEncodingForFunctionDecl(const FunctionDecl *Decl) const;
- /// \brief Emit the encoded type for the method declaration \p Decl into
+ /// Emit the encoded type for the method declaration \p Decl into
/// \p S.
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
bool Extended = false) const;
- /// \brief Return the encoded type for this block declaration.
+ /// Return the encoded type for this block declaration.
std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const;
/// getObjCEncodingForPropertyDecl - Return the encoded type for
@@ -1785,15 +1813,15 @@ public:
const ObjCPropertyDecl *PD,
const Decl *Container) const;
- /// \brief Return the size of type \p T for Objective-C encoding purpose,
+ /// Return the size of type \p T for Objective-C encoding purpose,
/// in characters.
CharUnits getObjCEncodingTypeSize(QualType T) const;
- /// \brief Retrieve the typedef corresponding to the predefined \c id type
+ /// Retrieve the typedef corresponding to the predefined \c id type
/// in Objective-C.
TypedefDecl *getObjCIdDecl() const;
- /// \brief Represents the Objective-CC \c id type.
+ /// Represents the Objective-CC \c id type.
///
/// This is set up lazily, by Sema. \c id is always a (typedef for a)
/// pointer type, a pointer to a struct.
@@ -1801,21 +1829,21 @@ public:
return getTypeDeclType(getObjCIdDecl());
}
- /// \brief Retrieve the typedef corresponding to the predefined 'SEL' type
+ /// Retrieve the typedef corresponding to the predefined 'SEL' type
/// in Objective-C.
TypedefDecl *getObjCSelDecl() const;
- /// \brief Retrieve the type that corresponds to the predefined Objective-C
+ /// Retrieve the type that corresponds to the predefined Objective-C
/// 'SEL' type.
QualType getObjCSelType() const {
return getTypeDeclType(getObjCSelDecl());
}
- /// \brief Retrieve the typedef declaration corresponding to the predefined
+ /// Retrieve the typedef declaration corresponding to the predefined
/// Objective-C 'Class' type.
TypedefDecl *getObjCClassDecl() const;
- /// \brief Represents the Objective-C \c Class type.
+ /// Represents the Objective-C \c Class type.
///
/// This is set up lazily, by Sema. \c Class is always a (typedef for a)
/// pointer type, a pointer to a struct.
@@ -1823,40 +1851,40 @@ public:
return getTypeDeclType(getObjCClassDecl());
}
- /// \brief Retrieve the Objective-C class declaration corresponding to
+ /// Retrieve the Objective-C class declaration corresponding to
/// the predefined \c Protocol class.
ObjCInterfaceDecl *getObjCProtocolDecl() const;
- /// \brief Retrieve declaration of 'BOOL' typedef
+ /// Retrieve declaration of 'BOOL' typedef
TypedefDecl *getBOOLDecl() const {
return BOOLDecl;
}
- /// \brief Save declaration of 'BOOL' typedef
+ /// Save declaration of 'BOOL' typedef
void setBOOLDecl(TypedefDecl *TD) {
BOOLDecl = TD;
}
- /// \brief type of 'BOOL' type.
+ /// type of 'BOOL' type.
QualType getBOOLType() const {
return getTypeDeclType(getBOOLDecl());
}
- /// \brief Retrieve the type of the Objective-C \c Protocol class.
+ /// Retrieve the type of the Objective-C \c Protocol class.
QualType getObjCProtoType() const {
return getObjCInterfaceType(getObjCProtocolDecl());
}
- /// \brief Retrieve the C type declaration corresponding to the predefined
+ /// Retrieve the C type declaration corresponding to the predefined
/// \c __builtin_va_list type.
TypedefDecl *getBuiltinVaListDecl() const;
- /// \brief Retrieve the type of the \c __builtin_va_list type.
+ /// Retrieve the type of the \c __builtin_va_list type.
QualType getBuiltinVaListType() const {
return getTypeDeclType(getBuiltinVaListDecl());
}
- /// \brief Retrieve the C type declaration corresponding to the predefined
+ /// Retrieve the C type declaration corresponding to the predefined
/// \c __va_list_tag type used to help define the \c __builtin_va_list type
/// for some targets.
Decl *getVaListTagDecl() const;
@@ -1870,18 +1898,22 @@ public:
return getTypeDeclType(getBuiltinMSVaListDecl());
}
- /// \brief Return a type with additional \c const, \c volatile, or
+ /// Return whether a declaration to a builtin is allowed to be
+ /// overloaded/redeclared.
+ bool canBuiltinBeRedeclared(const FunctionDecl *) const;
+
+ /// Return a type with additional \c const, \c volatile, or
/// \c restrict qualifiers.
QualType getCVRQualifiedType(QualType T, unsigned CVR) const {
return getQualifiedType(T, Qualifiers::fromCVRMask(CVR));
}
- /// \brief Un-split a SplitQualType.
+ /// Un-split a SplitQualType.
QualType getQualifiedType(SplitQualType split) const {
return getQualifiedType(split.Ty, split.Quals);
}
- /// \brief Return a type with additional qualifiers.
+ /// Return a type with additional qualifiers.
QualType getQualifiedType(QualType T, Qualifiers Qs) const {
if (!Qs.hasNonFastQualifiers())
return T.withFastQualifiers(Qs.getFastQualifiers());
@@ -1890,14 +1922,14 @@ public:
return getExtQualType(Ptr, Qc);
}
- /// \brief Return a type with additional qualifiers.
+ /// Return a type with additional qualifiers.
QualType getQualifiedType(const Type *T, Qualifiers Qs) const {
if (!Qs.hasNonFastQualifiers())
return QualType(T, Qs.getFastQualifiers());
return getExtQualType(T, Qs);
}
- /// \brief Return a type with the given lifetime qualifier.
+ /// Return a type with the given lifetime qualifier.
///
/// \pre Neither type.ObjCLifetime() nor \p lifetime may be \c OCL_None.
QualType getLifetimeQualifiedType(QualType type,
@@ -1921,6 +1953,9 @@ public:
return getQualifiedType(type.getUnqualifiedType(), Qs);
}
+ unsigned char getFixedPointScale(QualType Ty) const;
+ unsigned char getFixedPointIBits(QualType Ty) const;
+
DeclarationNameInfo getNameForTemplate(TemplateName Name,
SourceLocation NameLoc) const;
@@ -1954,7 +1989,7 @@ public:
GE_Missing_ucontext
};
- /// \brief Return the type for the specified builtin.
+ /// Return the type for the specified builtin.
///
/// If \p IntegerConstantArgs is non-null, it is filled in with a bitmask of
/// arguments to the builtin that are required to be integer constant
@@ -1962,6 +1997,10 @@ public:
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error,
unsigned *IntegerConstantArgs = nullptr) const;
+ /// Types and expressions required to build C++2a three-way comparisons
+ /// using operator<=>, including the values return by builtin <=> operators.
+ ComparisonCategories CompCategories;
+
private:
CanQualType getFromTargetType(unsigned Type) const;
TypeInfo getTypeInfoImpl(const Type *T) const;
@@ -1971,18 +2010,18 @@ private:
//===--------------------------------------------------------------------===//
public:
- /// \brief Return one of the GCNone, Weak or Strong Objective-C garbage
+ /// Return one of the GCNone, Weak or Strong Objective-C garbage
/// collection attributes.
Qualifiers::GC getObjCGCAttrKind(QualType Ty) const;
- /// \brief Return true if the given vector types are of the same unqualified
+ /// Return true if the given vector types are of the same unqualified
/// type or if they are equivalent to the same GCC vector type.
///
/// \note This ignores whether they are target-specific (AltiVec or Neon)
/// types.
bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec);
- /// \brief Return true if this is an \c NSObject object with its \c NSObject
+ /// Return true if this is an \c NSObject object with its \c NSObject
/// attribute set.
static bool isObjCNSObjectType(QualType Ty) {
return Ty->isObjCNSObjectType();
@@ -1992,48 +2031,48 @@ public:
// Type Sizing and Analysis
//===--------------------------------------------------------------------===//
- /// \brief Return the APFloat 'semantics' for the specified scalar floating
+ /// Return the APFloat 'semantics' for the specified scalar floating
/// point type.
const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const;
- /// \brief Get the size and alignment of the specified complete type in bits.
+ /// Get the size and alignment of the specified complete type in bits.
TypeInfo getTypeInfo(const Type *T) const;
TypeInfo getTypeInfo(QualType T) const { return getTypeInfo(T.getTypePtr()); }
- /// \brief Get default simd alignment of the specified complete type in bits.
+ /// Get default simd alignment of the specified complete type in bits.
unsigned getOpenMPDefaultSimdAlign(QualType T) const;
- /// \brief Return the size of the specified (complete) type \p T, in bits.
+ /// Return the size of the specified (complete) type \p T, in bits.
uint64_t getTypeSize(QualType T) const { return getTypeInfo(T).Width; }
uint64_t getTypeSize(const Type *T) const { return getTypeInfo(T).Width; }
- /// \brief Return the size of the character type, in bits.
+ /// Return the size of the character type, in bits.
uint64_t getCharWidth() const {
return getTypeSize(CharTy);
}
- /// \brief Convert a size in bits to a size in characters.
+ /// Convert a size in bits to a size in characters.
CharUnits toCharUnitsFromBits(int64_t BitSize) const;
- /// \brief Convert a size in characters to a size in bits.
+ /// Convert a size in characters to a size in bits.
int64_t toBits(CharUnits CharSize) const;
- /// \brief Return the size of the specified (complete) type \p T, in
+ /// Return the size of the specified (complete) type \p T, in
/// characters.
CharUnits getTypeSizeInChars(QualType T) const;
CharUnits getTypeSizeInChars(const Type *T) const;
- /// \brief Return the ABI-specified alignment of a (complete) type \p T, in
+ /// Return the ABI-specified alignment of a (complete) type \p T, in
/// bits.
unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; }
unsigned getTypeAlign(const Type *T) const { return getTypeInfo(T).Align; }
- /// \brief Return the ABI-specified alignment of a type, in bits, or 0 if
+ /// Return the ABI-specified alignment of a type, in bits, or 0 if
/// the type is incomplete and we cannot determine the alignment (for
/// example, from alignment attributes).
unsigned getTypeAlignIfKnown(QualType T) const;
- /// \brief Return the ABI-specified alignment of a (complete) type \p T, in
+ /// Return the ABI-specified alignment of a (complete) type \p T, in
/// characters.
CharUnits getTypeAlignInChars(QualType T) const;
CharUnits getTypeAlignInChars(const Type *T) const;
@@ -2045,31 +2084,31 @@ public:
std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T) const;
std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T) const;
- /// \brief Determine if the alignment the type has was required using an
+ /// Determine if the alignment the type has was required using an
/// alignment attribute.
bool isAlignmentRequired(const Type *T) const;
bool isAlignmentRequired(QualType T) const;
- /// \brief Return the "preferred" alignment of the specified type \p T for
+ /// Return the "preferred" alignment of the specified type \p T for
/// the current target, in bits.
///
/// This can be different than the ABI alignment in cases where it is
/// beneficial for performance to overalign a data type.
unsigned getPreferredTypeAlign(const Type *T) const;
- /// \brief Return the default alignment for __attribute__((aligned)) on
+ /// Return the default alignment for __attribute__((aligned)) on
/// this target, to be used if no alignment value is specified.
unsigned getTargetDefaultAlignForAttributeAligned() const;
- /// \brief Return the alignment in bits that should be given to a
+ /// Return the alignment in bits that should be given to a
/// global variable with type \p T.
unsigned getAlignOfGlobalVar(QualType T) const;
- /// \brief Return the alignment in characters that should be given to a
+ /// Return the alignment in characters that should be given to a
/// global variable with type \p T.
CharUnits getAlignOfGlobalVarInChars(QualType T) const;
- /// \brief Return a conservative estimate of the alignment of the specified
+ /// Return a conservative estimate of the alignment of the specified
/// decl \p D.
///
/// \pre \p D must not be a bitfield type, as bitfields do not have a valid
@@ -2081,12 +2120,12 @@ public:
/// pointers and large arrays get extra alignment.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof = false) const;
- /// \brief Get or compute information about the layout of the specified
+ /// Get or compute information about the layout of the specified
/// record (struct/union/class) \p D, which indicates its size and field
/// position information.
const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const;
- /// \brief Get or compute information about the layout of the specified
+ /// Get or compute information about the layout of the specified
/// Objective-C interface.
const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D)
const;
@@ -2094,14 +2133,14 @@ public:
void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS,
bool Simple = false) const;
- /// \brief Get or compute information about the layout of the specified
+ /// Get or compute information about the layout of the specified
/// Objective-C implementation.
///
/// This may differ from the interface if synthesized ivars are present.
const ASTRecordLayout &
getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const;
- /// \brief Get our current best idea for the key function of the
+ /// Get our current best idea for the key function of the
/// given record decl, or nullptr if there isn't one.
///
/// The key function is, according to the Itanium C++ ABI section 5.2.3:
@@ -2113,7 +2152,7 @@ public:
/// the result of this computation can change.
const CXXMethodDecl *getCurrentKeyFunction(const CXXRecordDecl *RD);
- /// \brief Observe that the given method cannot be a key function.
+ /// Observe that the given method cannot be a key function.
/// Checks the key-function cache for the method's class and clears it
/// if matches the given declaration.
///
@@ -2155,7 +2194,7 @@ public:
void CollectInheritedProtocols(const Decl *CDecl,
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
- /// \brief Return true if the specified type has unique object representations
+ /// Return true if the specified type has unique object representations
/// according to (C++17 [meta.unary.prop]p9)
bool hasUniqueObjectRepresentations(QualType Ty) const;
@@ -2163,7 +2202,7 @@ public:
// Type Operators
//===--------------------------------------------------------------------===//
- /// \brief Return the canonical (structural) type corresponding to the
+ /// Return the canonical (structural) type corresponding to the
/// specified potentially non-canonical type \p T.
///
/// The non-canonical version of a type may have many "decorated" versions of
@@ -2179,14 +2218,14 @@ public:
return T->getCanonicalTypeInternal().getTypePtr();
}
- /// \brief Return the canonical parameter type corresponding to the specific
+ /// Return the canonical parameter type corresponding to the specific
/// potentially non-canonical one.
///
/// Qualifiers are stripped off, functions are turned into function
/// pointers, and arrays decay one level into pointers.
CanQualType getCanonicalParamType(QualType T) const;
- /// \brief Determine whether the given types \p T1 and \p T2 are equivalent.
+ /// Determine whether the given types \p T1 and \p T2 are equivalent.
bool hasSameType(QualType T1, QualType T2) const {
return getCanonicalType(T1) == getCanonicalType(T2);
}
@@ -2194,7 +2233,7 @@ public:
return getCanonicalType(T1) == getCanonicalType(T2);
}
- /// \brief Return this type as a completely-unqualified array type,
+ /// Return this type as a completely-unqualified array type,
/// capturing the qualifiers in \p Quals.
///
/// This will remove the minimal amount of sugaring from the types, similar
@@ -2209,7 +2248,7 @@ public:
/// that corresponds to it. Otherwise, returns T.getUnqualifiedType().
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals);
- /// \brief Determine whether the given types are equivalent after
+ /// Determine whether the given types are equivalent after
/// cvr-qualifiers have been removed.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const {
return getCanonicalType(T1).getTypePtr() ==
@@ -2249,9 +2288,22 @@ public:
bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
const ObjCMethodDecl *MethodImp);
- bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2);
+ bool UnwrapSimilarTypes(QualType &T1, QualType &T2);
+ bool UnwrapSimilarArrayTypes(QualType &T1, QualType &T2);
+
+ /// Determine if two types are similar, according to the C++ rules. That is,
+ /// determine if they are the same other than qualifiers on the initial
+ /// sequence of pointer / pointer-to-member / array (and in Clang, object
+ /// pointer) types and their element types.
+ ///
+ /// Clang offers a number of qualifiers in addition to the C++ qualifiers;
+ /// those qualifiers are also ignored in the 'similarity' check.
+ bool hasSimilarType(QualType T1, QualType T2);
+
+ /// Determine if two types are similar, ignoring only CVR qualifiers.
+ bool hasCvrSimilarType(QualType T1, QualType T2);
- /// \brief Retrieves the "canonical" nested name specifier for a
+ /// Retrieves the "canonical" nested name specifier for a
/// given nested name specifier.
///
/// The canonical nested name specifier is a nested name specifier
@@ -2277,11 +2329,11 @@ public:
NestedNameSpecifier *
getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const;
- /// \brief Retrieves the default calling convention for the current target.
+ /// Retrieves the default calling convention for the current target.
CallingConv getDefaultCallingConvention(bool IsVariadic,
bool IsCXXMethod) const;
- /// \brief Retrieves the "canonical" template name that refers to a
+ /// Retrieves the "canonical" template name that refers to a
/// given template.
///
/// The canonical template name is the simplest expression that can
@@ -2301,11 +2353,11 @@ public:
/// types, values, and templates.
TemplateName getCanonicalTemplateName(TemplateName Name) const;
- /// \brief Determine whether the given template names refer to the same
+ /// Determine whether the given template names refer to the same
/// template.
bool hasSameTemplateName(TemplateName X, TemplateName Y);
- /// \brief Retrieve the "canonical" template argument.
+ /// Retrieve the "canonical" template argument.
///
/// The canonical template argument is the simplest template argument
/// (which may be a type, value, expression, or declaration) that
@@ -2332,33 +2384,33 @@ public:
return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T));
}
- /// \brief Return the innermost element type of an array type.
+ /// Return the innermost element type of an array type.
///
/// For example, will return "int" for int[m][n]
QualType getBaseElementType(const ArrayType *VAT) const;
- /// \brief Return the innermost element type of a type (which needn't
+ /// Return the innermost element type of a type (which needn't
/// actually be an array type).
QualType getBaseElementType(QualType QT) const;
- /// \brief Return number of constant array elements.
+ /// Return number of constant array elements.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
- /// \brief Perform adjustment on the parameter type of a function.
+ /// Perform adjustment on the parameter type of a function.
///
/// This routine adjusts the given parameter type @p T to the actual
/// parameter type used by semantic analysis (C99 6.7.5.3p[7,8],
/// C++ [dcl.fct]p3). The adjusted parameter type is returned.
QualType getAdjustedParameterType(QualType T) const;
- /// \brief Retrieve the parameter type as adjusted for use in the signature
+ /// Retrieve the parameter type as adjusted for use in the signature
/// of a function, decaying array and function types and removing top-level
/// cv-qualifiers.
QualType getSignatureParameterType(QualType T) const;
QualType getExceptionObjectType(QualType T) const;
- /// \brief Return the properly qualified result of decaying the specified
+ /// Return the properly qualified result of decaying the specified
/// array type to a pointer.
///
/// This operation is non-trivial when handling typedefs etc. The canonical
@@ -2368,35 +2420,35 @@ public:
/// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
QualType getArrayDecayedType(QualType T) const;
- /// \brief Return the type that \p PromotableType will promote to: C99
+ /// Return the type that \p PromotableType will promote to: C99
/// 6.3.1.1p2, assuming that \p PromotableType is a promotable integer type.
QualType getPromotedIntegerType(QualType PromotableType) const;
- /// \brief Recurses in pointer/array types until it finds an Objective-C
+ /// Recurses in pointer/array types until it finds an Objective-C
/// retainable type and returns its ownership.
Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const;
- /// \brief Whether this is a promotable bitfield reference according
+ /// Whether this is a promotable bitfield reference according
/// to C99 6.3.1.1p2, bullet 2 (and GCC extensions).
///
/// \returns the type this bit-field will promote to, or NULL if no
/// promotion occurs.
QualType isPromotableBitField(Expr *E) const;
- /// \brief Return the highest ranked integer type, see C99 6.3.1.8p1.
+ /// Return the highest ranked integer type, see C99 6.3.1.8p1.
///
/// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If
/// \p LHS < \p RHS, return -1.
int getIntegerTypeOrder(QualType LHS, QualType RHS) const;
- /// \brief Compare the rank of the two specified floating point types,
+ /// Compare the rank of the two specified floating point types,
/// ignoring the domain of the type (i.e. 'double' == '_Complex double').
///
/// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If
/// \p LHS < \p RHS, return -1.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const;
- /// \brief Return a real floating point or a complex type (based on
+ /// Return a real floating point or a complex type (based on
/// \p typeDomain/\p typeSize).
///
/// \param typeDomain a real floating point or complex type.
@@ -2521,13 +2573,20 @@ public:
// Per C99 6.2.5p6, for every signed integer type, there is a corresponding
// unsigned integer type. This method takes a signed type, and returns the
// corresponding unsigned integer type.
+ // With the introduction of fixed point types in ISO N1169, this method also
+ // accepts fixed point types and returns the corresponding unsigned type for
+ // a given fixed point type.
QualType getCorrespondingUnsignedType(QualType T) const;
+ // Per ISO N1169, this method accepts fixed point types and returns the
+ // corresponding saturated type for a given fixed point type.
+ QualType getCorrespondingSaturatedType(QualType Ty) const;
+
//===--------------------------------------------------------------------===//
// Integer Values
//===--------------------------------------------------------------------===//
- /// \brief Make an APSInt of the appropriate width and signedness for the
+ /// Make an APSInt of the appropriate width and signedness for the
/// given \p Value and integer \p Type.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const {
// If Type is a signed integer type larger than 64 bits, we need to be sure
@@ -2542,28 +2601,28 @@ public:
bool isSentinelNullExpr(const Expr *E);
- /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or nullptr if
+ /// Get the implementation of the ObjCInterfaceDecl \p D, or nullptr if
/// none exists.
ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D);
- /// \brief Get the implementation of the ObjCCategoryDecl \p D, or nullptr if
+ /// Get the implementation of the ObjCCategoryDecl \p D, or nullptr if
/// none exists.
ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);
- /// \brief Return true if there is at least one \@implementation in the TU.
+ /// Return true if there is at least one \@implementation in the TU.
bool AnyObjCImplementation() {
return !ObjCImpls.empty();
}
- /// \brief Set the implementation of ObjCInterfaceDecl.
+ /// Set the implementation of ObjCInterfaceDecl.
void setObjCImplementation(ObjCInterfaceDecl *IFaceD,
ObjCImplementationDecl *ImplD);
- /// \brief Set the implementation of ObjCCategoryDecl.
+ /// Set the implementation of ObjCCategoryDecl.
void setObjCImplementation(ObjCCategoryDecl *CatD,
ObjCCategoryImplDecl *ImplD);
- /// \brief Get the duplicate declaration of a ObjCMethod in the same
+ /// Get the duplicate declaration of a ObjCMethod in the same
/// interface, or null if none exists.
const ObjCMethodDecl *
getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const;
@@ -2571,19 +2630,19 @@ public:
void setObjCMethodRedeclaration(const ObjCMethodDecl *MD,
const ObjCMethodDecl *Redecl);
- /// \brief Returns the Objective-C interface that \p ND belongs to if it is
+ /// Returns the Objective-C interface that \p ND belongs to if it is
/// an Objective-C method/property/ivar etc. that is part of an interface,
/// otherwise returns null.
const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const;
- /// \brief Set the copy inialization expression of a block var decl.
+ /// Set the copy inialization expression of a block var decl.
void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
- /// \brief Get the copy initialization expression of the VarDecl \p VD, or
+ /// Get the copy initialization expression of the VarDecl \p VD, or
/// nullptr if none exists.
Expr *getBlockVarCopyInits(const VarDecl* VD);
- /// \brief Allocate an uninitialized TypeSourceInfo.
+ /// Allocate an uninitialized TypeSourceInfo.
///
/// The caller should initialize the memory held by TypeSourceInfo using
/// the TypeLoc wrappers.
@@ -2596,14 +2655,14 @@ public:
/// should be calculated based on the type.
TypeSourceInfo *CreateTypeSourceInfo(QualType T, unsigned Size = 0) const;
- /// \brief Allocate a TypeSourceInfo where all locations have been
+ /// Allocate a TypeSourceInfo where all locations have been
/// initialized to a given location, which defaults to the empty
/// location.
TypeSourceInfo *
getTrivialTypeSourceInfo(QualType T,
SourceLocation Loc = SourceLocation()) const;
- /// \brief Add a deallocation callback that will be invoked when the
+ /// Add a deallocation callback that will be invoked when the
/// ASTContext is destroyed.
///
/// \param Callback A callback function that will be invoked on destruction.
@@ -2625,7 +2684,7 @@ public:
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
- /// \brief Determines if the decl can be CodeGen'ed or deserialized from PCH
+ /// Determines if the decl can be CodeGen'ed or deserialized from PCH
/// lazily, only when used; this is only relevant for function or file scoped
/// var definitions.
///
@@ -2633,6 +2692,12 @@ public:
/// it is not used.
bool DeclMustBeEmitted(const Decl *D);
+ /// Visits all versions of a multiversioned function with the passed
+ /// predicate.
+ void forEachMultiversionedFunctionVersion(
+ const FunctionDecl *FD,
+ llvm::function_ref<void(const FunctionDecl *)> Pred) const;
+
const CXXConstructorDecl *
getCopyConstructorForExceptionObject(CXXRecordDecl *RD);
@@ -2653,21 +2718,21 @@ public:
void setStaticLocalNumber(const VarDecl *VD, unsigned Number);
unsigned getStaticLocalNumber(const VarDecl *VD) const;
- /// \brief Retrieve the context for computing mangling numbers in the given
+ /// Retrieve the context for computing mangling numbers in the given
/// DeclContext.
MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
std::unique_ptr<MangleNumberingContext> createMangleNumberingContext() const;
- /// \brief Used by ParmVarDecl to store on the side the
+ /// Used by ParmVarDecl to store on the side the
/// index of the parameter when it exceeds the size of the normal bitfield.
void setParameterIndex(const ParmVarDecl *D, unsigned index);
- /// \brief Used by ParmVarDecl to retrieve on the side the
+ /// Used by ParmVarDecl to retrieve on the side the
/// index of the parameter when it exceeds the size of the normal bitfield.
unsigned getParameterIndex(const ParmVarDecl *D) const;
- /// \brief Get the storage for the constant value of a materialized temporary
+ /// Get the storage for the constant value of a materialized temporary
/// of static storage duration.
APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
bool MayCreate);
@@ -2676,50 +2741,50 @@ public:
// Statistics
//===--------------------------------------------------------------------===//
- /// \brief The number of implicitly-declared default constructors.
+ /// The number of implicitly-declared default constructors.
static unsigned NumImplicitDefaultConstructors;
- /// \brief The number of implicitly-declared default constructors for
+ /// The number of implicitly-declared default constructors for
/// which declarations were built.
static unsigned NumImplicitDefaultConstructorsDeclared;
- /// \brief The number of implicitly-declared copy constructors.
+ /// The number of implicitly-declared copy constructors.
static unsigned NumImplicitCopyConstructors;
- /// \brief The number of implicitly-declared copy constructors for
+ /// The number of implicitly-declared copy constructors for
/// which declarations were built.
static unsigned NumImplicitCopyConstructorsDeclared;
- /// \brief The number of implicitly-declared move constructors.
+ /// The number of implicitly-declared move constructors.
static unsigned NumImplicitMoveConstructors;
- /// \brief The number of implicitly-declared move constructors for
+ /// The number of implicitly-declared move constructors for
/// which declarations were built.
static unsigned NumImplicitMoveConstructorsDeclared;
- /// \brief The number of implicitly-declared copy assignment operators.
+ /// The number of implicitly-declared copy assignment operators.
static unsigned NumImplicitCopyAssignmentOperators;
- /// \brief The number of implicitly-declared copy assignment operators for
+ /// The number of implicitly-declared copy assignment operators for
/// which declarations were built.
static unsigned NumImplicitCopyAssignmentOperatorsDeclared;
- /// \brief The number of implicitly-declared move assignment operators.
+ /// The number of implicitly-declared move assignment operators.
static unsigned NumImplicitMoveAssignmentOperators;
- /// \brief The number of implicitly-declared move assignment operators for
+ /// The number of implicitly-declared move assignment operators for
/// which declarations were built.
static unsigned NumImplicitMoveAssignmentOperatorsDeclared;
- /// \brief The number of implicitly-declared destructors.
+ /// The number of implicitly-declared destructors.
static unsigned NumImplicitDestructors;
- /// \brief The number of implicitly-declared destructors for which
+ /// The number of implicitly-declared destructors for which
/// declarations were built.
static unsigned NumImplicitDestructorsDeclared;
public:
- /// \brief Initialize built-in types.
+ /// Initialize built-in types.
///
/// This routine may only be invoked once for a given ASTContext object.
/// It is normally invoked after ASTContext construction.
@@ -2756,7 +2821,7 @@ public:
QualType T, std::string& S,
bool Extended) const;
- /// \brief Returns true if this is an inline-initialized static data member
+ /// 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;
@@ -2774,7 +2839,7 @@ public:
Strong
};
- /// \brief Determine whether a definition of this inline variable should
+ /// Determine whether a definition of this inline variable should
/// be treated as a weak or strong definition. For compatibility with
/// C++14 and before, for a constexpr static data member, if there is an
/// out-of-line declaration of the member, we may promote it from weak to
@@ -2790,7 +2855,7 @@ private:
getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl) const;
- /// \brief A set of deallocations that should be performed when the
+ /// A set of deallocations that should be performed when the
/// ASTContext is destroyed.
// FIXME: We really should have a better mechanism in the ASTContext to
// manage running destructors for types which do variable sized allocation
@@ -2841,13 +2906,13 @@ public:
llvm::StringMap<SectionInfo> SectionInfos;
};
-/// \brief Utility function for constructing a nullary selector.
+/// Utility function for constructing a nullary selector.
inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(0, &II);
}
-/// \brief Utility function for constructing an unary selector.
+/// Utility function for constructing an unary selector.
inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(1, &II);
@@ -2857,7 +2922,7 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
// operator new and delete aren't allowed inside namespaces.
-/// @brief Placement new for using the ASTContext's allocator.
+/// Placement new for using the ASTContext's allocator.
///
/// This placement form of operator new uses the ASTContext's allocator for
/// obtaining memory.
@@ -2890,7 +2955,7 @@ inline void *operator new(size_t Bytes, const clang::ASTContext &C,
return C.Allocate(Bytes, Alignment);
}
-/// @brief Placement delete companion to the new above.
+/// Placement delete companion to the new above.
///
/// This operator is just a companion to the new above. There is no way of
/// invoking it directly; see the new operator for more details. This operator
@@ -2928,7 +2993,7 @@ inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
return C.Allocate(Bytes, Alignment);
}
-/// @brief Placement delete[] companion to the new[] above.
+/// Placement delete[] companion to the new[] above.
///
/// This operator is just a companion to the new[] above. There is no way of
/// invoking it directly; see the new[] operator for more details. This operator
@@ -2938,7 +3003,7 @@ inline void operator delete[](void *Ptr, const clang::ASTContext &C, size_t) {
C.Deallocate(Ptr);
}
-/// \brief Create the representation of a LazyGenerationalUpdatePtr.
+/// Create the representation of a LazyGenerationalUpdatePtr.
template <typename Owner, typename T,
void (clang::ExternalASTSource::*Update)(Owner)>
typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index 27c85e65f2c11..b08865dde3c10 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -24,7 +24,7 @@ namespace clang {
};
} // end namespace diag
- /// \brief DiagnosticsEngine argument formatting function for diagnostics that
+ /// DiagnosticsEngine argument formatting function for diagnostics that
/// involve AST nodes.
///
/// This function formats diagnostic arguments for various AST nodes,
diff --git a/include/clang/AST/ASTFwd.h b/include/clang/AST/ASTFwd.h
index 003d489c1ca40..038d5c3d36115 100644
--- a/include/clang/AST/ASTFwd.h
+++ b/include/clang/AST/ASTFwd.h
@@ -8,7 +8,7 @@
//===--------------------------------------------------------------===//
///
/// \file
-/// \brief Forward declaration of all AST node types.
+/// Forward declaration of all AST node types.
///
//===-------------------------------------------------------------===//
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index 66b9cd394b9d9..6e6a1926254bc 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -1,4 +1,4 @@
-//===--- ASTImporter.h - Importing ASTs from other Contexts -----*- C++ -*-===//
+//===- ASTImporter.h - Importing ASTs from other Contexts -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,82 +11,95 @@
// context into another context.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
#define LLVM_CLANG_AST_ASTIMPORTER_H
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
+#include <utility>
namespace clang {
- class ASTContext;
- class CXXCtorInitializer;
- class CXXBaseSpecifier;
- class Decl;
- class DeclContext;
- class DiagnosticsEngine;
- class Expr;
- class FileManager;
- class IdentifierInfo;
- class NestedNameSpecifier;
- class Stmt;
- class TypeSourceInfo;
-
- /// \brief Imports selected nodes from one AST context into another context,
+
+class ASTContext;
+class CXXBaseSpecifier;
+class CXXCtorInitializer;
+class Decl;
+class DeclContext;
+class Expr;
+class FileManager;
+class NamedDecl;
+class Stmt;
+class TagDecl;
+class TypeSourceInfo;
+class Attr;
+
+ // \brief Returns with a list of declarations started from the canonical decl
+ // then followed by subsequent decls in the translation unit.
+ // This gives a canonical list for each entry in the redecl chain.
+ // `Decl::redecls()` gives a list of decls which always start from the
+ // previous decl and the next item is actually the previous item in the order
+ // of source locations. Thus, `Decl::redecls()` gives different lists for
+ // the different entries in a given redecl chain.
+ llvm::SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D);
+
+ /// Imports selected nodes from one AST context into another context,
/// merging AST nodes where appropriate.
class ASTImporter {
public:
- typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
- typedef llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>
- ImportedCXXBaseSpecifierMap;
+ using NonEquivalentDeclSet = llvm::DenseSet<std::pair<Decl *, Decl *>>;
+ using ImportedCXXBaseSpecifierMap =
+ llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>;
private:
- /// \brief The contexts we're importing to and from.
+ /// The contexts we're importing to and from.
ASTContext &ToContext, &FromContext;
- /// \brief The file managers we're importing to and from.
+ /// The file managers we're importing to and from.
FileManager &ToFileManager, &FromFileManager;
- /// \brief Whether to perform a minimal import.
+ /// Whether to perform a minimal import.
bool Minimal;
- /// \brief Whether the last diagnostic came from the "from" context.
- bool LastDiagFromFrom;
+ /// Whether the last diagnostic came from the "from" context.
+ bool LastDiagFromFrom = false;
- /// \brief Mapping from the already-imported types in the "from" context
+ /// Mapping from the already-imported types in the "from" context
/// to the corresponding types in the "to" context.
llvm::DenseMap<const Type *, const Type *> ImportedTypes;
- /// \brief Mapping from the already-imported declarations in the "from"
+ /// Mapping from the already-imported declarations in the "from"
/// context to the corresponding declarations in the "to" context.
llvm::DenseMap<Decl *, Decl *> ImportedDecls;
- /// \brief Mapping from the already-imported statements in the "from"
+ /// Mapping from the already-imported statements in the "from"
/// context to the corresponding statements in the "to" context.
llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
- /// \brief Mapping from the already-imported FileIDs in the "from" source
+ /// Mapping from the already-imported FileIDs in the "from" source
/// manager to the corresponding FileIDs in the "to" source manager.
llvm::DenseMap<FileID, FileID> ImportedFileIDs;
- /// \brief Mapping from the already-imported CXXBasesSpecifier in
+ /// Mapping from the already-imported CXXBasesSpecifier in
/// the "from" source manager to the corresponding CXXBasesSpecifier
/// in the "to" source manager.
ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers;
-
- /// \brief Imported, anonymous tag declarations that are missing their
- /// corresponding typedefs.
- SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs;
- /// \brief Declaration (from, to) pairs that are known not to be equivalent
+ /// Declaration (from, to) pairs that are known not to be equivalent
/// (which we have already complained about).
NonEquivalentDeclSet NonEquivalentDecls;
public:
- /// \brief Create a new AST importer.
+ /// Create a new AST importer.
///
/// \param ToContext The context we'll be importing into.
///
@@ -105,135 +118,144 @@ namespace clang {
virtual ~ASTImporter();
- /// \brief Whether the importer will perform a minimal import, creating
+ /// Whether the importer will perform a minimal import, creating
/// to-be-completed forward declarations when possible.
bool isMinimalImport() const { return Minimal; }
- /// \brief Import the given type from the "from" context into the "to"
+ /// Import the given type from the "from" context into the "to"
/// context.
///
/// \returns the equivalent type in the "to" context, or a NULL type if
/// an error occurred.
QualType Import(QualType FromT);
- /// \brief Import the given type source information from the
+ /// Import the given type source information from the
/// "from" context into the "to" context.
///
/// \returns the equivalent type source information in the "to"
/// context, or NULL if an error occurred.
TypeSourceInfo *Import(TypeSourceInfo *FromTSI);
- /// \brief Import the given declaration from the "from" context into the
+ /// Import the given attribute from the "from" context into the
+ /// "to" context.
+ ///
+ /// \returns the equivalent attribute in the "to" context.
+ Attr *Import(const Attr *FromAttr);
+
+ /// Import the given declaration from the "from" context into the
/// "to" context.
///
/// \returns the equivalent declaration in the "to" context, or a NULL type
/// if an error occurred.
Decl *Import(Decl *FromD);
+ Decl *Import(const Decl *FromD) {
+ return Import(const_cast<Decl *>(FromD));
+ }
- /// \brief Return the copy of the given declaration in the "to" context if
+ /// Return the copy of the given declaration in the "to" context if
/// it has already been imported from the "from" context. Otherwise return
/// NULL.
Decl *GetAlreadyImportedOrNull(Decl *FromD);
- /// \brief Import the given declaration context from the "from"
+ /// Import the given declaration context from the "from"
/// AST context into the "to" AST context.
///
/// \returns the equivalent declaration context in the "to"
/// context, or a NULL type if an error occurred.
DeclContext *ImportContext(DeclContext *FromDC);
- /// \brief Import the given expression from the "from" context into the
+ /// Import the given expression from the "from" context into the
/// "to" context.
///
/// \returns the equivalent expression in the "to" context, or NULL if
/// an error occurred.
Expr *Import(Expr *FromE);
- /// \brief Import the given statement from the "from" context into the
+ /// Import the given statement from the "from" context into the
/// "to" context.
///
/// \returns the equivalent statement in the "to" context, or NULL if
/// an error occurred.
Stmt *Import(Stmt *FromS);
- /// \brief Import the given nested-name-specifier from the "from"
+ /// Import the given nested-name-specifier from the "from"
/// context into the "to" context.
///
/// \returns the equivalent nested-name-specifier in the "to"
/// context, or NULL if an error occurred.
NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
- /// \brief Import the given nested-name-specifier from the "from"
+ /// Import the given nested-name-specifier from the "from"
/// context into the "to" context.
///
/// \returns the equivalent nested-name-specifier in the "to"
/// context.
NestedNameSpecifierLoc Import(NestedNameSpecifierLoc FromNNS);
- /// \brief Import the goven template name from the "from" context into the
+ /// Import the goven template name from the "from" context into the
/// "to" context.
TemplateName Import(TemplateName From);
- /// \brief Import the given source location from the "from" context into
+ /// Import the given source location from the "from" context into
/// the "to" context.
///
/// \returns the equivalent source location in the "to" context, or an
/// invalid source location if an error occurred.
SourceLocation Import(SourceLocation FromLoc);
- /// \brief Import the given source range from the "from" context into
+ /// Import the given source range from the "from" context into
/// the "to" context.
///
/// \returns the equivalent source range in the "to" context, or an
/// invalid source location if an error occurred.
SourceRange Import(SourceRange FromRange);
- /// \brief Import the given declaration name from the "from"
+ /// Import the given declaration name from the "from"
/// context into the "to" context.
///
/// \returns the equivalent declaration name in the "to" context,
/// or an empty declaration name if an error occurred.
DeclarationName Import(DeclarationName FromName);
- /// \brief Import the given identifier from the "from" context
+ /// Import the given identifier from the "from" context
/// into the "to" context.
///
/// \returns the equivalent identifier in the "to" context.
IdentifierInfo *Import(const IdentifierInfo *FromId);
- /// \brief Import the given Objective-C selector from the "from"
+ /// Import the given Objective-C selector from the "from"
/// context into the "to" context.
///
/// \returns the equivalent selector in the "to" context.
Selector Import(Selector FromSel);
- /// \brief Import the given file ID from the "from" context into the
+ /// Import the given file ID from the "from" context into the
/// "to" context.
///
/// \returns the equivalent file ID in the source manager of the "to"
/// context.
FileID Import(FileID);
- /// \brief Import the given C++ constructor initializer from the "from"
+ /// Import the given C++ constructor initializer from the "from"
/// context into the "to" context.
///
/// \returns the equivalent initializer in the "to" context.
CXXCtorInitializer *Import(CXXCtorInitializer *FromInit);
- /// \brief Import the given CXXBaseSpecifier from the "from" context into
+ /// Import the given CXXBaseSpecifier from the "from" context into
/// the "to" context.
///
/// \returns the equivalent CXXBaseSpecifier in the source manager of the
/// "to" context.
CXXBaseSpecifier *Import(const CXXBaseSpecifier *FromSpec);
- /// \brief Import the definition of the given declaration, including all of
+ /// Import the definition of the given declaration, including all of
/// the declarations it contains.
///
/// This routine is intended to be used
void ImportDefinition(Decl *From);
- /// \brief Cope with a name conflict when importing a declaration into the
+ /// Cope with a name conflict when importing a declaration into the
/// given context.
///
/// This routine is invoked whenever there is a name conflict while
@@ -265,41 +287,41 @@ namespace clang {
NamedDecl **Decls,
unsigned NumDecls);
- /// \brief Retrieve the context that AST nodes are being imported into.
+ /// Retrieve the context that AST nodes are being imported into.
ASTContext &getToContext() const { return ToContext; }
- /// \brief Retrieve the context that AST nodes are being imported from.
+ /// Retrieve the context that AST nodes are being imported from.
ASTContext &getFromContext() const { return FromContext; }
- /// \brief Retrieve the file manager that AST nodes are being imported into.
+ /// Retrieve the file manager that AST nodes are being imported into.
FileManager &getToFileManager() const { return ToFileManager; }
- /// \brief Retrieve the file manager that AST nodes are being imported from.
+ /// Retrieve the file manager that AST nodes are being imported from.
FileManager &getFromFileManager() const { return FromFileManager; }
- /// \brief Report a diagnostic in the "to" context.
+ /// Report a diagnostic in the "to" context.
DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
- /// \brief Report a diagnostic in the "from" context.
+ /// Report a diagnostic in the "from" context.
DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
- /// \brief Return the set of declarations that we know are not equivalent.
+ /// Return the set of declarations that we know are not equivalent.
NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
- /// \brief Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl.
+ /// Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl.
/// Mark the Decl as complete, filling it in as much as possible.
///
/// \param D A declaration in the "to" context.
virtual void CompleteDecl(Decl* D);
- /// \brief Note that we have imported the "from" declaration by mapping it
- /// to the (potentially-newly-created) "to" declaration.
- ///
/// Subclasses can override this function to observe all of the \c From ->
/// \c To declaration mappings as they are imported.
- virtual Decl *Imported(Decl *From, Decl *To);
-
- /// \brief Called by StructuralEquivalenceContext. If a RecordDecl is
+ virtual Decl *Imported(Decl *From, Decl *To) { return To; }
+
+ /// Store and assign the imported declaration to its counterpart.
+ Decl *MapImported(Decl *From, Decl *To);
+
+ /// Called by StructuralEquivalenceContext. If a RecordDecl is
/// being compared to another RecordDecl as part of import, completing the
/// other RecordDecl may trigger importation of the first RecordDecl. This
/// happens especially for anonymous structs. If the original of the second
@@ -307,11 +329,12 @@ namespace clang {
/// importation, eliminating this loop.
virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }
- /// \brief Determine whether the given types are structurally
+ /// Determine whether the given types are structurally
/// equivalent.
bool IsStructurallyEquivalent(QualType From, QualType To,
bool Complain = true);
};
-}
+
+} // namespace clang
#endif // LLVM_CLANG_AST_ASTIMPORTER_H
diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h
index 69df2d8c01138..2fe4e2563b36f 100644
--- a/include/clang/AST/ASTLambda.h
+++ b/include/clang/AST/ASTLambda.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief This file provides some common utility functions for processing
+/// This file provides some common utility functions for processing
/// Lambda related AST Constructs.
///
//===----------------------------------------------------------------------===//
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index 9395d36d87e58..31ae2b111e013 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -41,86 +41,86 @@ namespace clang {
class VarTemplateDecl;
class VarTemplateSpecializationDecl;
-/// \brief An abstract interface that should be implemented by listeners
+/// An abstract interface that should be implemented by listeners
/// that want to be notified when an AST entity gets modified after its
/// initial creation.
class ASTMutationListener {
public:
virtual ~ASTMutationListener();
- /// \brief A new TagDecl definition was completed.
+ /// A new TagDecl definition was completed.
virtual void CompletedTagDefinition(const TagDecl *D) { }
- /// \brief A new declaration with name has been added to a DeclContext.
+ /// A new declaration with name has been added to a DeclContext.
virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D) {}
- /// \brief An implicit member was added after the definition was completed.
+ /// An implicit member was added after the definition was completed.
virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {}
- /// \brief A template specialization (or partial one) was added to the
+ /// A template specialization (or partial one) was added to the
/// template declaration.
virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
const ClassTemplateSpecializationDecl *D) {}
- /// \brief A template specialization (or partial one) was added to the
+ /// A template specialization (or partial one) was added to the
/// template declaration.
virtual void
AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
const VarTemplateSpecializationDecl *D) {}
- /// \brief A template specialization (or partial one) was added to the
+ /// A template specialization (or partial one) was added to the
/// template declaration.
virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
const FunctionDecl *D) {}
- /// \brief A function's exception specification has been evaluated or
+ /// 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.
+ /// A function's return type has been deduced.
virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType);
- /// \brief A virtual destructor's operator delete has been resolved.
+ /// A virtual destructor's operator delete has been resolved.
virtual void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
const FunctionDecl *Delete,
Expr *ThisArg) {}
- /// \brief An implicit member got a definition.
+ /// An implicit member got a definition.
virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
- /// \brief The instantiation of a templated function or variable was
+ /// The instantiation of a templated function or variable was
/// requested. In particular, the point of instantiation and template
/// specialization kind of \p D may have changed.
virtual void InstantiationRequested(const ValueDecl *D) {}
- /// \brief A templated variable's definition was implicitly instantiated.
+ /// A templated variable's definition was implicitly instantiated.
virtual void VariableDefinitionInstantiated(const VarDecl *D) {}
- /// \brief A function template's definition was instantiated.
+ /// A function template's definition was instantiated.
virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {}
- /// \brief A default argument was instantiated.
+ /// A default argument was instantiated.
virtual void DefaultArgumentInstantiated(const ParmVarDecl *D) {}
- /// \brief A default member initializer was instantiated.
+ /// A default member initializer was instantiated.
virtual void DefaultMemberInitializerInstantiated(const FieldDecl *D) {}
- /// \brief A new objc category class was added for an interface.
+ /// A new objc category class was added for an interface.
virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) {}
- /// \brief A declaration is marked used which was not previously marked used.
+ /// A declaration is marked used which was not previously marked used.
///
/// \param D the declaration marked used
virtual void DeclarationMarkedUsed(const Decl *D) {}
- /// \brief A declaration is marked as OpenMP threadprivate which was not
+ /// A declaration is marked as OpenMP threadprivate which was not
/// previously marked as threadprivate.
///
/// \param D the declaration marked OpenMP threadprivate.
virtual void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {}
- /// \brief A declaration is marked as OpenMP declaretarget which was not
+ /// A declaration is marked as OpenMP declaretarget which was not
/// previously marked as declaretarget.
///
/// \param D the declaration marked OpenMP declaretarget.
@@ -128,14 +128,14 @@ public:
virtual void DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
const Attr *Attr) {}
- /// \brief A definition has been made visible by being redefined locally.
+ /// A definition has been made visible by being redefined locally.
///
/// \param D The definition that was previously not visible.
/// \param M The containing module in which the definition was made visible,
/// if any.
virtual void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {}
- /// \brief An attribute was added to a RecordDecl
+ /// An attribute was added to a RecordDecl
///
/// \param Attr The attribute that was added to the Record
///
diff --git a/include/clang/AST/ASTStructuralEquivalence.h b/include/clang/AST/ASTStructuralEquivalence.h
index 23674c65f332f..d32f87d43e041 100644
--- a/include/clang/AST/ASTStructuralEquivalence.h
+++ b/include/clang/AST/ASTStructuralEquivalence.h
@@ -1,4 +1,4 @@
-//===--- ASTStructuralEquivalence.h - ---------------------------*- C++ -*-===//
+//===- ASTStructuralEquivalence.h -------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,6 +19,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include <deque>
+#include <utility>
namespace clang {
@@ -29,6 +30,14 @@ class QualType;
class RecordDecl;
class SourceLocation;
+/// \brief Whether to perform a normal or minimal equivalence check.
+/// In case of `Minimal`, we do not perform a recursive check of decls with
+/// external storage.
+enum class StructuralEquivalenceKind {
+ Default,
+ Minimal,
+};
+
struct StructuralEquivalenceContext {
/// AST contexts for which we are checking structural equivalence.
ASTContext &FromCtx, &ToCtx;
@@ -46,6 +55,8 @@ struct StructuralEquivalenceContext {
/// (which we have already complained about).
llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls;
+ StructuralEquivalenceKind EqKind;
+
/// Whether we're being strict about the spelling of types when
/// unifying two types.
bool StrictTypeSpelling;
@@ -57,27 +68,35 @@ struct StructuralEquivalenceContext {
bool Complain;
/// \c true if the last diagnostic came from ToCtx.
- bool LastDiagFromC2;
+ bool LastDiagFromC2 = false;
StructuralEquivalenceContext(
ASTContext &FromCtx, ASTContext &ToCtx,
llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
+ StructuralEquivalenceKind EqKind,
bool StrictTypeSpelling = false, bool Complain = true,
bool ErrorOnTagTypeMismatch = false)
: FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
- StrictTypeSpelling(StrictTypeSpelling),
- ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain),
- LastDiagFromC2(false) {}
+ EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling),
+ ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain) {}
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
/// Determine whether the two declarations are structurally
/// equivalent.
- bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
+ /// Implementation functions (all static functions in
+ /// ASTStructuralEquivalence.cpp) must never call this function because that
+ /// will wreak havoc the internal state (\c DeclsToCheck and
+ /// \c TentativeEquivalences members) and can cause faulty equivalent results.
+ bool IsEquivalent(Decl *D1, Decl *D2);
/// Determine whether the two types are structurally equivalent.
- bool IsStructurallyEquivalent(QualType T1, QualType T2);
+ /// Implementation functions (all static functions in
+ /// ASTStructuralEquivalence.cpp) must never call this function because that
+ /// will wreak havoc the internal state (\c DeclsToCheck and
+ /// \c TentativeEquivalences members) and can cause faulty equivalent results.
+ bool IsEquivalent(QualType T1, QualType T2);
/// Find the index of the given anonymous struct/union within its
/// context.
@@ -98,6 +117,7 @@ private:
/// \returns true if an error occurred, false otherwise.
bool Finish();
};
+
} // namespace clang
#endif // LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
index 51d60a90a146b..9df9793370c4a 100644
--- a/include/clang/AST/ASTTypeTraits.h
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -38,62 +38,62 @@ struct PrintingPolicy;
namespace ast_type_traits {
-/// \brief Kind identifier.
+/// Kind identifier.
///
/// It can be constructed from any node kind and allows for runtime type
/// hierarchy checks.
/// Use getFromNodeKind<T>() to construct them.
class ASTNodeKind {
public:
- /// \brief Empty identifier. It matches nothing.
+ /// Empty identifier. It matches nothing.
ASTNodeKind() : KindId(NKI_None) {}
- /// \brief Construct an identifier for T.
+ /// Construct an identifier for T.
template <class T>
static ASTNodeKind getFromNodeKind() {
return ASTNodeKind(KindToKindId<T>::Id);
}
/// \{
- /// \brief Construct an identifier for the dynamic type of the node
+ /// Construct an identifier for the dynamic type of the node
static ASTNodeKind getFromNode(const Decl &D);
static ASTNodeKind getFromNode(const Stmt &S);
static ASTNodeKind getFromNode(const Type &T);
/// \}
- /// \brief Returns \c true if \c this and \c Other represent the same kind.
+ /// Returns \c true if \c this and \c Other represent the same kind.
bool isSame(ASTNodeKind Other) const {
return KindId != NKI_None && KindId == Other.KindId;
}
- /// \brief Returns \c true only for the default \c ASTNodeKind()
+ /// Returns \c true only for the default \c ASTNodeKind()
bool isNone() const { return KindId == NKI_None; }
- /// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
+ /// Returns \c true if \c this is a base kind of (or same as) \c Other.
/// \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.
+ /// String representation of the kind.
StringRef asStringRef() const;
- /// \brief Strict weak ordering for ASTNodeKind.
+ /// Strict weak ordering for ASTNodeKind.
bool operator<(const ASTNodeKind &Other) const {
return KindId < Other.KindId;
}
- /// \brief Return the most derived type between \p Kind1 and \p Kind2.
+ /// Return the most derived type between \p Kind1 and \p Kind2.
///
/// Return ASTNodeKind() if they are not related.
static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2);
- /// \brief Return the most derived common ancestor between Kind1 and Kind2.
+ /// Return the most derived common ancestor between Kind1 and Kind2.
///
/// Return ASTNodeKind() if they are not related.
static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1,
ASTNodeKind Kind2);
- /// \brief Hooks for using ASTNodeKind as a key in a DenseMap.
+ /// Hooks for using ASTNodeKind as a key in a DenseMap.
struct DenseMapInfo {
// ASTNodeKind() is a good empty key because it is represented as a 0.
static inline ASTNodeKind getEmptyKey() { return ASTNodeKind(); }
@@ -115,7 +115,7 @@ public:
}
private:
- /// \brief Kind ids.
+ /// Kind ids.
///
/// Includes all possible base and derived kinds.
enum NodeKindId {
@@ -140,16 +140,16 @@ private:
NKI_NumberOfKinds
};
- /// \brief Use getFromNodeKind<T>() to construct the kind.
+ /// Use getFromNodeKind<T>() to construct the kind.
ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
- /// \brief Returns \c true if \c Base is a base kind of (or same as) \c
+ /// Returns \c true if \c Base is a base kind of (or same as) \c
/// 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.
+ /// Helper meta-function to convert a kind T to its enum value.
///
/// This struct is specialized below for all known kinds.
template <class T> struct KindToKindId {
@@ -158,11 +158,11 @@ private:
template <class T>
struct KindToKindId<const T> : KindToKindId<T> {};
- /// \brief Per kind info.
+ /// Per kind info.
struct KindInfo {
- /// \brief The id of the parent kind, or None if it has no parent.
+ /// The id of the parent kind, or None if it has no parent.
NodeKindId ParentId;
- /// \brief Name of the kind.
+ /// Name of the kind.
const char *Name;
};
static const KindInfo AllKindInfo[NKI_NumberOfKinds];
@@ -197,7 +197,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
return OS;
}
-/// \brief A dynamically typed AST node container.
+/// A dynamically typed AST node container.
///
/// Stores an AST node in a type safe way. This allows writing code that
/// works with different kinds of AST nodes, despite the fact that they don't
@@ -211,13 +211,13 @@ inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
/// the supported base types.
class DynTypedNode {
public:
- /// \brief Creates a \c DynTypedNode from \c Node.
+ /// Creates a \c DynTypedNode from \c Node.
template <typename T>
static DynTypedNode create(const T &Node) {
return BaseConverter<T>::create(Node);
}
- /// \brief Retrieve the stored node as type \c T.
+ /// Retrieve the stored node as type \c T.
///
/// Returns NULL if the stored node does not have a type that is
/// convertible to \c T.
@@ -234,7 +234,7 @@ public:
return BaseConverter<T>::get(NodeKind, Storage.buffer);
}
- /// \brief Retrieve the stored node as type \c T.
+ /// Retrieve the stored node as type \c T.
///
/// Similar to \c get(), but asserts that the type is what we are expecting.
template <typename T>
@@ -244,7 +244,7 @@ public:
ASTNodeKind getNodeKind() const { return NodeKind; }
- /// \brief Returns a pointer that identifies the stored AST node.
+ /// Returns a pointer that identifies the stored AST node.
///
/// Note that this is not supported by all AST nodes. For AST nodes
/// that don't have a pointer-defined identity inside the AST, this
@@ -255,21 +255,21 @@ public:
: nullptr;
}
- /// \brief Prints the node to the given output stream.
+ /// Prints the node to the given output stream.
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
- /// \brief Dumps the node to the given output stream.
+ /// Dumps the node to the given output stream.
void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
- /// \brief For nodes which represent textual entities in the source code,
+ /// For nodes which represent textual entities in the source code,
/// return their SourceRange. For all other nodes, return SourceRange().
SourceRange getSourceRange() const;
/// @{
- /// \brief Imposes an order on \c DynTypedNode.
+ /// Imposes an order on \c DynTypedNode.
///
/// Supports comparison of nodes that support memoization.
- /// FIXME: Implement comparsion for other node types (currently
+ /// FIXME: Implement comparison for other node types (currently
/// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
bool operator<(const DynTypedNode &Other) const {
if (!NodeKind.isSame(Other.NodeKind))
@@ -326,7 +326,7 @@ public:
}
/// @}
- /// \brief Hooks for using DynTypedNode as a key in a DenseMap.
+ /// Hooks for using DynTypedNode as a key in a DenseMap.
struct DenseMapInfo {
static inline DynTypedNode getEmptyKey() {
DynTypedNode Node;
@@ -368,10 +368,10 @@ public:
};
private:
- /// \brief Takes care of converting from and to \c T.
+ /// Takes care of converting from and to \c T.
template <typename T, typename EnablerT = void> struct BaseConverter;
- /// \brief Converter that uses dyn_cast<T> from a stored BaseT*.
+ /// Converter that uses dyn_cast<T> from a stored BaseT*.
template <typename T, typename BaseT> struct DynCastPtrConverter {
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
@@ -391,7 +391,7 @@ private:
}
};
- /// \brief Converter that stores T* (by pointer).
+ /// Converter that stores T* (by pointer).
template <typename T> struct PtrConverter {
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
@@ -411,7 +411,7 @@ private:
}
};
- /// \brief Converter that stores T (by value).
+ /// Converter that stores T (by value).
template <typename T> struct ValueConverter {
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
@@ -432,7 +432,7 @@ private:
ASTNodeKind NodeKind;
- /// \brief Stores the data of the node.
+ /// Stores the data of the node.
///
/// Note that we can store \c Decls, \c Stmts, \c Types,
/// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
index 3693aeccfe14f..9bf63bb6e2d7d 100644
--- a/include/clang/AST/ASTUnresolvedSet.h
+++ b/include/clang/AST/ASTUnresolvedSet.h
@@ -26,7 +26,7 @@ namespace clang {
class NamedDecl;
-/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
+/// An UnresolvedSet-like class which uses the ASTContext's allocator.
class ASTUnresolvedSet {
friend class LazyASTUnresolvedSet;
@@ -89,7 +89,7 @@ public:
const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; }
};
-/// \brief An UnresolvedSet-like class that might not have been loaded from the
+/// An UnresolvedSet-like class that might not have been loaded from the
/// external AST source yet.
class LazyASTUnresolvedSet {
mutable ASTUnresolvedSet Impl;
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index bbe320c28a3b5..32a61c59d2368 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -23,9 +23,9 @@
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
@@ -52,8 +52,10 @@ protected:
unsigned Inherited : 1;
unsigned IsPackExpansion : 1;
unsigned Implicit : 1;
+ // FIXME: These are properties of the attribute kind, not state for this
+ // instance of the attribute.
unsigned IsLateParsed : 1;
- unsigned DuplicatesAllowed : 1;
+ unsigned InheritEvenIfAlreadyPresent : 1;
void *operator new(size_t bytes) noexcept {
llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
@@ -74,10 +76,10 @@ public:
protected:
Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed, bool DuplicatesAllowed)
+ bool IsLateParsed)
: Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
Inherited(false), IsPackExpansion(false), Implicit(false),
- IsLateParsed(IsLateParsed), DuplicatesAllowed(DuplicatesAllowed) {}
+ IsLateParsed(IsLateParsed), InheritEvenIfAlreadyPresent(false) {}
public:
@@ -94,7 +96,7 @@ public:
bool isInherited() const { return Inherited; }
- /// \brief Returns true if the attribute has been implicitly created instead
+ /// 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; }
@@ -109,18 +111,13 @@ public:
// Pretty print this attribute.
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
-
- /// \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.
- bool duplicatesAllowed() const { return DuplicatesAllowed; }
};
class StmtAttr : public Attr {
protected:
StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed, bool DuplicatesAllowed)
- : Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {}
+ bool IsLateParsed)
+ : Attr(AK, R, SpellingListIndex, IsLateParsed) {}
public:
static bool classof(const Attr *A) {
@@ -132,12 +129,20 @@ public:
class InheritableAttr : public Attr {
protected:
InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed, bool DuplicatesAllowed)
- : Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {}
+ bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
+ : Attr(AK, R, SpellingListIndex, IsLateParsed) {
+ this->InheritEvenIfAlreadyPresent = InheritEvenIfAlreadyPresent;
+ }
public:
void setInherited(bool I) { Inherited = I; }
+ /// Should this attribute be inherited from a prior declaration even if it's
+ /// explicitly provided in the current declaration?
+ bool shouldInheritEvenIfAlreadyPresent() const {
+ return InheritEvenIfAlreadyPresent;
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
return A->getKind() >= attr::FirstInheritableAttr &&
@@ -148,9 +153,9 @@ public:
class InheritableParamAttr : public InheritableAttr {
protected:
InheritableParamAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed, bool DuplicatesAllowed)
+ bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
: InheritableAttr(AK, R, SpellingListIndex, IsLateParsed,
- DuplicatesAllowed) {}
+ InheritEvenIfAlreadyPresent) {}
public:
// Implement isa/cast/dyncast/etc.
@@ -166,9 +171,9 @@ class ParameterABIAttr : public InheritableParamAttr {
protected:
ParameterABIAttr(attr::Kind AK, SourceRange R,
unsigned SpellingListIndex, bool IsLateParsed,
- bool DuplicatesAllowed)
+ bool InheritEvenIfAlreadyPresent)
: InheritableParamAttr(AK, R, SpellingListIndex, IsLateParsed,
- DuplicatesAllowed) {}
+ InheritEvenIfAlreadyPresent) {}
public:
ParameterABI getABI() const {
@@ -190,6 +195,128 @@ public:
}
};
+/// A single parameter index whose accessors require each use to make explicit
+/// the parameter index encoding needed.
+class ParamIdx {
+ // Idx is exposed only via accessors that specify specific encodings.
+ unsigned Idx : 30;
+ unsigned HasThis : 1;
+ unsigned IsValid : 1;
+
+ void assertComparable(const ParamIdx &I) const {
+ assert(isValid() && I.isValid() &&
+ "ParamIdx must be valid to be compared");
+ // It's possible to compare indices from separate functions, but so far
+ // it's not proven useful. Moreover, it might be confusing because a
+ // comparison on the results of getASTIndex might be inconsistent with a
+ // comparison on the ParamIdx objects themselves.
+ assert(HasThis == I.HasThis &&
+ "ParamIdx must be for the same function to be compared");
+ }
+
+public:
+ /// Construct an invalid parameter index (\c isValid returns false and
+ /// accessors fail an assert).
+ ParamIdx() : Idx(0), HasThis(false), IsValid(false) {}
+
+ /// \param Idx is the parameter index as it is normally specified in
+ /// attributes in the source: one-origin including any C++ implicit this
+ /// parameter.
+ ///
+ /// \param D is the declaration containing the parameters. It is used to
+ /// determine if there is a C++ implicit this parameter.
+ ParamIdx(unsigned Idx, const Decl *D)
+ : Idx(Idx), HasThis(false), IsValid(true) {
+ assert(Idx >= 1 && "Idx must be one-origin");
+ if (const auto *FD = dyn_cast<FunctionDecl>(D))
+ HasThis = FD->isCXXInstanceMember();
+ }
+
+ /// A type into which \c ParamIdx can be serialized.
+ ///
+ /// A static assertion that it's of the correct size follows the \c ParamIdx
+ /// class definition.
+ typedef uint32_t SerialType;
+
+ /// Produce a representation that can later be passed to \c deserialize to
+ /// construct an equivalent \c ParamIdx.
+ SerialType serialize() const {
+ return *reinterpret_cast<const SerialType *>(this);
+ }
+
+ /// Construct from a result from \c serialize.
+ static ParamIdx deserialize(SerialType S) {
+ ParamIdx P(*reinterpret_cast<ParamIdx *>(&S));
+ assert((!P.IsValid || P.Idx >= 1) && "valid Idx must be one-origin");
+ return P;
+ }
+
+ /// Is this parameter index valid?
+ bool isValid() const { return IsValid; }
+
+ /// Get the parameter index as it would normally be encoded for attributes at
+ /// the source level of representation: one-origin including any C++ implicit
+ /// this parameter.
+ ///
+ /// This encoding thus makes sense for diagnostics, pretty printing, and
+ /// constructing new attributes from a source-like specification.
+ unsigned getSourceIndex() const {
+ assert(isValid() && "ParamIdx must be valid");
+ return Idx;
+ }
+
+ /// Get the parameter index as it would normally be encoded at the AST level
+ /// of representation: zero-origin not including any C++ implicit this
+ /// parameter.
+ ///
+ /// This is the encoding primarily used in Sema. However, in diagnostics,
+ /// Sema uses \c getSourceIndex instead.
+ unsigned getASTIndex() const {
+ assert(isValid() && "ParamIdx must be valid");
+ assert(Idx >= 1 + HasThis &&
+ "stored index must be base-1 and not specify C++ implicit this");
+ return Idx - 1 - HasThis;
+ }
+
+ /// Get the parameter index as it would normally be encoded at the LLVM level
+ /// of representation: zero-origin including any C++ implicit this parameter.
+ ///
+ /// This is the encoding primarily used in CodeGen.
+ unsigned getLLVMIndex() const {
+ assert(isValid() && "ParamIdx must be valid");
+ assert(Idx >= 1 && "stored index must be base-1");
+ return Idx - 1;
+ }
+
+ bool operator==(const ParamIdx &I) const {
+ assertComparable(I);
+ return Idx == I.Idx;
+ }
+ bool operator!=(const ParamIdx &I) const {
+ assertComparable(I);
+ return Idx != I.Idx;
+ }
+ bool operator<(const ParamIdx &I) const {
+ assertComparable(I);
+ return Idx < I.Idx;
+ }
+ bool operator>(const ParamIdx &I) const {
+ assertComparable(I);
+ return Idx > I.Idx;
+ }
+ bool operator<=(const ParamIdx &I) const {
+ assertComparable(I);
+ return Idx <= I.Idx;
+ }
+ bool operator>=(const ParamIdx &I) const {
+ assertComparable(I);
+ return Idx >= I.Idx;
+ }
+};
+
+static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType),
+ "ParamIdx does not fit its serialization type");
+
#include "clang/AST/Attrs.inc"
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
diff --git a/include/clang/AST/Availability.h b/include/clang/AST/Availability.h
index 5ed8313784567..28f3c3c01d200 100644
--- a/include/clang/AST/Availability.h
+++ b/include/clang/AST/Availability.h
@@ -15,12 +15,12 @@
#define LLVM_CLANG_AST_AVAILABILITY_H
#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/VersionTuple.h"
namespace clang {
-/// \brief One specifier in an @available expression.
+/// One specifier in an @available expression.
///
/// \code
/// @available(macos 10.10, *)
diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def
index e4f5f7db2f73c..400efcb1981f1 100644
--- a/include/clang/AST/BuiltinTypes.def
+++ b/include/clang/AST/BuiltinTypes.def
@@ -72,6 +72,9 @@ UNSIGNED_TYPE(UChar, UnsignedCharTy)
// 'wchar_t' for targets where it's unsigned
SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(WChar_U, WCharTy))
+// 'char8_t' in C++20 (proposed)
+UNSIGNED_TYPE(Char8, Char8Ty)
+
// 'char16_t' in C++
UNSIGNED_TYPE(Char16, Char16Ty)
@@ -119,6 +122,80 @@ SIGNED_TYPE(LongLong, LongLongTy)
// '__int128_t'
SIGNED_TYPE(Int128, Int128Ty)
+//===- Fixed point types --------------------------------------------------===//
+
+// 'short _Accum'
+SIGNED_TYPE(ShortAccum, ShortAccumTy)
+
+// '_Accum'
+SIGNED_TYPE(Accum, AccumTy)
+
+// 'long _Accum'
+SIGNED_TYPE(LongAccum, LongAccumTy)
+
+// 'unsigned short _Accum'
+UNSIGNED_TYPE(UShortAccum, UnsignedShortAccumTy)
+
+// 'unsigned _Accum'
+UNSIGNED_TYPE(UAccum, UnsignedAccumTy)
+
+// 'unsigned long _Accum'
+UNSIGNED_TYPE(ULongAccum, UnsignedLongAccumTy)
+
+// 'short _Fract'
+SIGNED_TYPE(ShortFract, ShortFractTy)
+
+// '_Fract'
+SIGNED_TYPE(Fract, FractTy)
+
+// 'long _Fract'
+SIGNED_TYPE(LongFract, LongFractTy)
+
+// 'unsigned short _Fract'
+UNSIGNED_TYPE(UShortFract, UnsignedShortFractTy)
+
+// 'unsigned _Fract'
+UNSIGNED_TYPE(UFract, UnsignedFractTy)
+
+// 'unsigned long _Fract'
+UNSIGNED_TYPE(ULongFract, UnsignedLongFractTy)
+
+// '_Sat short _Accum'
+SIGNED_TYPE(SatShortAccum, SatShortAccumTy)
+
+// '_Sat _Accum'
+SIGNED_TYPE(SatAccum, SatAccumTy)
+
+// '_Sat long _Accum'
+SIGNED_TYPE(SatLongAccum, SatLongAccumTy)
+
+// '_Sat unsigned short _Accum'
+UNSIGNED_TYPE(SatUShortAccum, SatUnsignedShortAccumTy)
+
+// '_Sat unsigned _Accum'
+UNSIGNED_TYPE(SatUAccum, SatUnsignedAccumTy)
+
+// '_Sat unsigned long _Accum'
+UNSIGNED_TYPE(SatULongAccum, SatUnsignedLongAccumTy)
+
+// '_Sat short _Fract'
+SIGNED_TYPE(SatShortFract, SatShortFractTy)
+
+// '_Sat _Fract'
+SIGNED_TYPE(SatFract, SatFractTy)
+
+// '_Sat long _Fract'
+SIGNED_TYPE(SatLongFract, SatLongFractTy)
+
+// '_Sat unsigned short _Fract'
+UNSIGNED_TYPE(SatUShortFract, SatUnsignedShortFractTy)
+
+// '_Sat unsigned _Fract'
+UNSIGNED_TYPE(SatUFract, SatUnsignedFractTy)
+
+// '_Sat unsigned long _Fract'
+UNSIGNED_TYPE(SatULongFract, SatUnsignedLongFractTy)
+
//===- Floating point types -----------------------------------------------===//
// 'half' in OpenCL, '__fp16' in ARM NEON.
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 11fb229f0c091..2ae1d8b25823b 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -35,7 +35,7 @@ namespace clang {
class ASTContext;
class NamedDecl;
-/// \brief Represents an element in a path from a derived class to a
+/// Represents an element in a path from a derived class to a
/// base class.
///
/// Each step in the path references the link from a
@@ -43,15 +43,15 @@ class NamedDecl;
/// base "number" that identifies which base subobject of the
/// original derived class we are referencing.
struct CXXBasePathElement {
- /// \brief The base specifier that states the link from a derived
+ /// The base specifier that states the link from a derived
/// class to a base class, which will be followed by this base
/// path element.
const CXXBaseSpecifier *Base;
- /// \brief The record decl of the class that the base is a base of.
+ /// The record decl of the class that the base is a base of.
const CXXRecordDecl *Class;
- /// \brief Identifies which base class subobject (of type
+ /// Identifies which base class subobject (of type
/// \c Base->getType()) this base path element refers to.
///
/// This value is only valid if \c !Base->isVirtual(), because there
@@ -60,7 +60,7 @@ struct CXXBasePathElement {
int SubobjectNumber;
};
-/// \brief Represents a path from a specific derived class
+/// Represents a path from a specific derived class
/// (which is not represented as part of the path) to a particular
/// (direct or indirect) base class subobject.
///
@@ -70,14 +70,14 @@ struct CXXBasePathElement {
/// subobject is being used.
class CXXBasePath : public SmallVector<CXXBasePathElement, 4> {
public:
- /// \brief The access along this inheritance path. This is only
+ /// The access along this inheritance path. This is only
/// calculated when recording paths. AS_none is a special value
/// used to indicate a path which permits no legal access.
AccessSpecifier Access = AS_public;
CXXBasePath() = default;
- /// \brief The set of declarations found inside this base class
+ /// The set of declarations found inside this base class
/// subobject.
DeclContext::lookup_result Decls;
@@ -119,24 +119,42 @@ public:
class CXXBasePaths {
friend class CXXRecordDecl;
- /// \brief The type from which this search originated.
+ /// The type from which this search originated.
CXXRecordDecl *Origin = nullptr;
/// Paths - The actual set of paths that can be taken from the
/// derived class to the same base class.
std::list<CXXBasePath> Paths;
-
+
/// ClassSubobjects - Records the class subobjects for each class
- /// type that we've seen. The first element in the pair says
+ /// type that we've seen. The first element IsVirtBase says
/// whether we found a path to a virtual base for that class type,
- /// while the element contains the number of non-virtual base
+ /// while NumberOfNonVirtBases contains the number of non-virtual base
/// class subobjects for that class type. The key of the map is
/// the cv-unqualified canonical type of the base class subobject.
- llvm::SmallDenseMap<QualType, std::pair<bool, unsigned>, 8> ClassSubobjects;
+ struct IsVirtBaseAndNumberNonVirtBases {
+ unsigned IsVirtBase : 1;
+ unsigned NumberOfNonVirtBases : 31;
+ };
+ llvm::SmallDenseMap<QualType, IsVirtBaseAndNumberNonVirtBases, 8>
+ ClassSubobjects;
/// VisitedDependentRecords - Records the dependent records that have been
/// already visited.
- llvm::SmallDenseSet<const CXXRecordDecl *, 4> VisitedDependentRecords;
+ llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedDependentRecords;
+
+ /// DetectedVirtual - The base class that is virtual.
+ const RecordType *DetectedVirtual = nullptr;
+
+ /// ScratchPath - A BasePath that is used by Sema::lookupInBases
+ /// to help build the set of paths.
+ CXXBasePath ScratchPath;
+
+ /// Array of the declarations that have been found. This
+ /// array is constructed only if needed, e.g., to iterate over the
+ /// results within LookupResult.
+ std::unique_ptr<NamedDecl *[]> DeclsFound;
+ unsigned NumDeclsFound = 0;
/// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
/// ambiguous paths while it is looking for a path from a derived
@@ -152,20 +170,7 @@ class CXXBasePaths {
/// if it finds a path that goes across a virtual base. The virtual class
/// is also recorded.
bool DetectVirtual;
-
- /// ScratchPath - A BasePath that is used by Sema::lookupInBases
- /// to help build the set of paths.
- CXXBasePath ScratchPath;
- /// DetectedVirtual - The base class that is virtual.
- const RecordType *DetectedVirtual = nullptr;
-
- /// \brief Array of the declarations that have been found. This
- /// array is constructed only if needed, e.g., to iterate over the
- /// results within LookupResult.
- std::unique_ptr<NamedDecl *[]> DeclsFound;
- unsigned NumDeclsFound = 0;
-
void ComputeDeclsFound();
bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record,
@@ -196,53 +201,53 @@ public:
decl_range found_decls();
- /// \brief Determine whether the path from the most-derived type to the
+ /// Determine whether the path from the most-derived type to the
/// given base type is ambiguous (i.e., it refers to multiple subobjects of
/// the same base type).
bool isAmbiguous(CanQualType BaseType);
- /// \brief Whether we are finding multiple paths to detect ambiguities.
+ /// Whether we are finding multiple paths to detect ambiguities.
bool isFindingAmbiguities() const { return FindAmbiguities; }
- /// \brief Whether we are recording paths.
+ /// Whether we are recording paths.
bool isRecordingPaths() const { return RecordPaths; }
- /// \brief Specify whether we should be recording paths or not.
+ /// Specify whether we should be recording paths or not.
void setRecordingPaths(bool RP) { RecordPaths = RP; }
- /// \brief Whether we are detecting virtual bases.
+ /// Whether we are detecting virtual bases.
bool isDetectingVirtual() const { return DetectVirtual; }
- /// \brief The virtual base discovered on the path (if we are merely
+ /// The virtual base discovered on the path (if we are merely
/// detecting virtuals).
const RecordType* getDetectedVirtual() const {
return DetectedVirtual;
}
- /// \brief Retrieve the type from which this base-paths search
+ /// Retrieve the type from which this base-paths search
/// began
CXXRecordDecl *getOrigin() const { return Origin; }
void setOrigin(CXXRecordDecl *Rec) { Origin = Rec; }
- /// \brief Clear the base-paths results.
+ /// Clear the base-paths results.
void clear();
- /// \brief Swap this data structure's contents with another CXXBasePaths
+ /// Swap this data structure's contents with another CXXBasePaths
/// object.
void swap(CXXBasePaths &Other);
};
-/// \brief Uniquely identifies a virtual method within a class
+/// Uniquely identifies a virtual method within a class
/// hierarchy by the method itself and a class subobject number.
struct UniqueVirtualMethod {
- /// \brief The overriding virtual method.
+ /// The overriding virtual method.
CXXMethodDecl *Method = nullptr;
- /// \brief The subobject in which the overriding virtual method
+ /// The subobject in which the overriding virtual method
/// resides.
unsigned Subobject = 0;
- /// \brief The virtual base class subobject of which this overridden
+ /// The virtual base class subobject of which this overridden
/// virtual method is a part. Note that this records the closest
/// derived virtual base class subobject.
const CXXRecordDecl *InVirtualSubobject = nullptr;
@@ -266,7 +271,7 @@ struct UniqueVirtualMethod {
}
};
-/// \brief The set of methods that override a given virtual method in
+/// The set of methods that override a given virtual method in
/// each subobject where it occurs.
///
/// The first part of the pair is the subobject in which the
@@ -310,7 +315,7 @@ public:
void replaceAll(UniqueVirtualMethod Overriding);
};
-/// \brief A mapping from each virtual member function to its set of
+/// A mapping from each virtual member function to its set of
/// final overriders.
///
/// Within a class hierarchy for a given derived class, each virtual
@@ -364,7 +369,7 @@ public:
class CXXFinalOverriderMap
: public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> {};
-/// \brief A set of all the primary bases for a class.
+/// A set of all the primary bases for a class.
class CXXIndirectPrimaryBaseSet
: public llvm::SmallSet<const CXXRecordDecl*, 32> {};
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 6487613200de3..63a0af66eec37 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -44,7 +44,7 @@ class TemplateTypeParmDecl;
// Canonical, qualified type template
//----------------------------------------------------------------------------//
-/// \brief Represents a canonical, potentially-qualified type.
+/// Represents a canonical, potentially-qualified type.
///
/// The CanQual template is a lightweight smart pointer that provides access
/// to the canonical representation of a type, where all typedefs and other
@@ -64,35 +64,35 @@ class TemplateTypeParmDecl;
/// a call to ASTContext::getCanonicalType().
template<typename T = Type>
class CanQual {
- /// \brief The actual, canonical type.
+ /// The actual, canonical type.
QualType Stored;
public:
- /// \brief Constructs a NULL canonical type.
+ /// Constructs a NULL canonical type.
CanQual() = default;
- /// \brief Converting constructor that permits implicit upcasting of
+ /// Converting constructor that permits implicit upcasting of
/// canonical type pointers.
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
+ /// Retrieve the underlying type pointer, which refers to a
/// canonical type.
///
/// The underlying pointer must not be nullptr.
const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
- /// \brief Retrieve the underlying type pointer, which refers to a
+ /// Retrieve the underlying type pointer, which refers to a
/// canonical type, or nullptr.
const T *getTypePtrOrNull() const {
return cast_or_null<T>(Stored.getTypePtrOrNull());
}
- /// \brief Implicit conversion to a qualified type.
+ /// Implicit conversion to a qualified type.
operator QualType() const { return Stored; }
- /// \brief Implicit conversion to bool.
+ /// Implicit conversion to bool.
explicit operator bool() const { return !isNull(); }
bool isNull() const {
@@ -101,7 +101,7 @@ public:
SplitQualType split() const { return Stored.split(); }
- /// \brief Retrieve a canonical type pointer with a different static type,
+ /// Retrieve a canonical type pointer with a different static type,
/// upcasting or downcasting as needed.
///
/// The getAs() function is typically used to try to downcast to a
@@ -122,17 +122,17 @@ public:
template<typename U> CanProxy<U> castAs() const;
- /// \brief Overloaded arrow operator that produces a canonical type
+ /// Overloaded arrow operator that produces a canonical type
/// proxy.
CanProxy<T> operator->() const;
- /// \brief Retrieve all qualifiers.
+ /// Retrieve all qualifiers.
Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
- /// \brief Retrieve the const/volatile/restrict qualifiers.
+ /// Retrieve the const/volatile/restrict qualifiers.
unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
- /// \brief Determines whether this type has any qualifiers
+ /// Determines whether this type has any qualifiers
bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
bool isConstQualified() const {
@@ -147,45 +147,45 @@ public:
return Stored.isLocalRestrictQualified();
}
- /// \brief Determines if this canonical type is furthermore
+ /// Determines if this canonical type is furthermore
/// canonical as a parameter. The parameter-canonicalization
/// process decays arrays to pointers and drops top-level qualifiers.
bool isCanonicalAsParam() const {
return Stored.isCanonicalAsParam();
}
- /// \brief Retrieve the unqualified form of this type.
+ /// Retrieve the unqualified form of this type.
CanQual<T> getUnqualifiedType() const;
- /// \brief Retrieves a version of this type with const applied.
+ /// Retrieves a version of this type with const applied.
/// Note that this does not always yield a canonical type.
QualType withConst() const {
return Stored.withConst();
}
- /// \brief Determines whether this canonical type is more qualified than
+ /// Determines whether this canonical type is more qualified than
/// the @p Other canonical type.
bool isMoreQualifiedThan(CanQual<T> Other) const {
return Stored.isMoreQualifiedThan(Other.Stored);
}
- /// \brief Determines whether this canonical type is at least as qualified as
+ /// Determines whether this canonical type is at least as qualified as
/// the @p Other canonical type.
bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
return Stored.isAtLeastAsQualifiedAs(Other.Stored);
}
- /// \brief If the canonical type is a reference type, returns the type that
+ /// If the canonical type is a reference type, returns the type that
/// it refers to; otherwise, returns the type itself.
CanQual<Type> getNonReferenceType() const;
- /// \brief Retrieve the internal representation of this canonical type.
+ /// Retrieve the internal representation of this canonical type.
void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
- /// \brief Construct a canonical type from its internal representation.
+ /// Construct a canonical type from its internal representation.
static CanQual<T> getFromOpaquePtr(void *Ptr);
- /// \brief Builds a canonical type from a QualType.
+ /// Builds a canonical type from a QualType.
///
/// This routine is inherently unsafe, because it requires the user to
/// ensure that the given type is a canonical type with the correct
@@ -209,7 +209,7 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) {
return x.getAsOpaquePtr() != y.getAsOpaquePtr();
}
-/// \brief Represents a canonical, potentially-qualified type.
+/// Represents a canonical, potentially-qualified type.
using CanQualType = CanQual<Type>;
inline CanQualType Type::getCanonicalTypeUnqualified() const {
@@ -234,7 +234,7 @@ return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor()); \
#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor) \
Type Accessor() const { return this->getTypePtr()->Accessor(); }
-/// \brief Base class of all canonical proxy types, which is responsible for
+/// Base class of all canonical proxy types, which is responsible for
/// storing the underlying canonical type and providing basic conversions.
template<typename T>
class CanProxyBase {
@@ -242,10 +242,10 @@ protected:
CanQual<T> Stored;
public:
- /// \brief Retrieve the pointer to the underlying Type
+ /// Retrieve the pointer to the underlying Type
const T *getTypePtr() const { return Stored.getTypePtr(); }
- /// \brief Implicit conversion to the underlying pointer.
+ /// Implicit conversion to the underlying pointer.
///
/// Also provides the ability to use canonical type proxies in a Boolean
// context,e.g.,
@@ -254,7 +254,7 @@ public:
/// @endcode
operator const T*() const { return this->Stored.getTypePtrOrNull(); }
- /// \brief Try to convert the given canonical type to a specific structural
+ /// Try to convert the given canonical type to a specific structural
/// type.
template<typename U> CanProxy<U> getAs() const {
return this->Stored.template getAs<U>();
@@ -313,7 +313,7 @@ public:
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
- /// \brief Retrieve the proxy-adaptor type.
+ /// Retrieve the proxy-adaptor type.
///
/// This arrow operator is used when CanProxyAdaptor has been specialized
/// for the given type T. In that case, we reference members of the
@@ -324,7 +324,7 @@ public:
}
};
-/// \brief Replacable canonical proxy adaptor class that provides the link
+/// Replaceable canonical proxy adaptor class that provides the link
/// between a canonical type and the accessors of the type.
///
/// The CanProxyAdaptor is a replaceable class template that is instantiated
@@ -337,7 +337,7 @@ public:
template<typename T>
struct CanProxyAdaptor : CanProxyBase<T> {};
-/// \brief Canonical proxy type returned when retrieving the members of a
+/// Canonical proxy type returned when retrieving the members of a
/// canonical type or as the result of the @c CanQual<T>::getAs member
/// function.
///
@@ -347,13 +347,13 @@ struct CanProxyAdaptor : CanProxyBase<T> {};
template<typename T>
class CanProxy : public CanProxyAdaptor<T> {
public:
- /// \brief Build a NULL proxy.
+ /// Build a NULL proxy.
CanProxy() = default;
- /// \brief Build a proxy to the given canonical type.
+ /// Build a proxy to the given canonical type.
CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
- /// \brief Implicit conversion to the stored canonical type.
+ /// Implicit conversion to the stored canonical type.
operator CanQual<T>() const { return this->Stored; }
};
@@ -396,7 +396,7 @@ namespace clang {
// Canonical proxy adaptors for canonical type nodes.
//----------------------------------------------------------------------------//
-/// \brief Iterator adaptor that turns an iterator over canonical QualTypes
+/// Iterator adaptor that turns an iterator over canonical QualTypes
/// into an iterator over CanQualTypes.
template <typename InputIterator>
struct CanTypeIterator
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index 94470cbf305f6..e3a427d8aa0d8 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -990,7 +990,7 @@ struct DeclInfo {
/// CurrentDecl is the declaration with which the FullComment is associated.
///
- /// It can be different from \c CommentDecl. It happens when we we decide
+ /// It can be different from \c CommentDecl. It happens when we decide
/// that the comment originally attached to \c CommentDecl is fine for
/// \c CurrentDecl too (for example, for a redeclaration or an overrider of
/// \c CommentDecl).
diff --git a/include/clang/AST/CommentBriefParser.h b/include/clang/AST/CommentBriefParser.h
index be5b8eeb80c34..baa22930539e5 100644
--- a/include/clang/AST/CommentBriefParser.h
+++ b/include/clang/AST/CommentBriefParser.h
@@ -24,7 +24,7 @@ namespace comments {
///
/// Due to a variety of comment styles, it considers the following as "a brief
/// description", in order of priority:
-/// \li a \\brief or \\short command,
+/// \li a \or \\short command,
/// \li the first paragraph,
/// \li a \\result or \\return or \\returns paragraph.
class BriefParser {
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h
index 289f2fd345afa..bac4e99dc7a4c 100644
--- a/include/clang/AST/CommentCommandTraits.h
+++ b/include/clang/AST/CommentCommandTraits.h
@@ -26,7 +26,7 @@
namespace clang {
namespace comments {
-/// \brief Information about a single command.
+/// Information about a single command.
///
/// When reordering, adding or removing members please update the corresponding
/// TableGen backend.
@@ -57,7 +57,7 @@ struct CommandInfo {
unsigned IsBlockCommand : 1;
/// True if this command is introducing a brief documentation
- /// paragraph (\\brief or an alias).
+ /// paragraph (\or an alias).
unsigned IsBriefCommand : 1;
/// True if this command is \\returns or an alias.
@@ -77,29 +77,29 @@ struct CommandInfo {
/// True if this command is \\deprecated or an alias.
unsigned IsDeprecatedCommand : 1;
- /// \brief True if this is a \\headerfile-like command.
+ /// True if this is a \\headerfile-like command.
unsigned IsHeaderfileCommand : 1;
/// True if we don't want to warn about this command being passed an empty
/// paragraph. Meaningful only for block commands.
unsigned IsEmptyParagraphAllowed : 1;
- /// \brief True if this command is a verbatim-like block command.
+ /// True if this command is a verbatim-like block command.
///
/// A verbatim-like block command eats every character (except line starting
/// decorations) until matching end command is seen or comment end is hit.
unsigned IsVerbatimBlockCommand : 1;
- /// \brief True if this command is an end command for a verbatim-like block.
+ /// True if this command is an end command for a verbatim-like block.
unsigned IsVerbatimBlockEndCommand : 1;
- /// \brief True if this command is a verbatim line command.
+ /// True if this command is a verbatim line command.
///
/// A verbatim-like line command eats everything until a newline is seen or
/// comment end is hit.
unsigned IsVerbatimLineCommand : 1;
- /// \brief True if this command contains a declaration for the entity being
+ /// True if this command contains a declaration for the entity being
/// documented.
///
/// For example:
@@ -108,17 +108,17 @@ struct CommandInfo {
/// \endcode
unsigned IsDeclarationCommand : 1;
- /// \brief True if verbatim-like line command is a function declaration.
+ /// True if verbatim-like line command is a function declaration.
unsigned IsFunctionDeclarationCommand : 1;
- /// \brief True if block command is further describing a container API; such
+ /// True if block command is further describing a container API; such
/// as \@coclass, \@classdesign, etc.
unsigned IsRecordLikeDetailCommand : 1;
- /// \brief True if block command is a container API; such as \@interface.
+ /// True if block command is a container API; such as \@interface.
unsigned IsRecordLikeDeclarationCommand : 1;
- /// \brief True if this command is unknown. This \c CommandInfo object was
+ /// True if this command is unknown. This \c CommandInfo object was
/// created during parsing.
unsigned IsUnknownCommand : 1;
};
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index 5bb075807be59..52c4eb9e309a1 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -52,7 +52,7 @@ enum TokenKind {
};
} // end namespace tok
-/// \brief Comment token.
+/// Comment token.
class Token {
friend class Lexer;
friend class TextTokenRetokenizer;
@@ -72,7 +72,7 @@ class Token {
/// Integer value associated with a token.
///
- /// If the token is a konwn command, contains command ID and TextPtr is
+ /// If the token is a known command, contains command ID and TextPtr is
/// unused (command spelling can be found with CommandTraits). Otherwise,
/// contains the length of the string that starts at TextPtr.
unsigned IntVal;
@@ -217,7 +217,7 @@ public:
void dump(const Lexer &L, const SourceManager &SM) const;
};
-/// \brief Comment lexer.
+/// Comment lexer.
class Lexer {
private:
Lexer(const Lexer &) = delete;
@@ -281,6 +281,11 @@ private:
/// command, including command marker.
SmallString<16> VerbatimBlockEndCommandName;
+ /// If true, the commands, html tags, etc will be parsed and reported as
+ /// separate tokens inside the comment body. If false, the comment text will
+ /// be parsed into text and newline tokens.
+ bool ParseCommands;
+
/// Given a character reference name (e.g., "lt"), return the character that
/// it stands for (e.g., "<").
StringRef resolveHTMLNamedCharacterReference(StringRef Name) const;
@@ -315,12 +320,11 @@ private:
/// Eat string matching regexp \code \s*\* \endcode.
void skipLineStartingDecorations();
- /// Lex stuff inside comments. CommentEnd should be set correctly.
+ /// Lex comment text, including commands if ParseCommands is set to true.
void lexCommentText(Token &T);
- void setupAndLexVerbatimBlock(Token &T,
- const char *TextBegin,
- char Marker, const CommandInfo *Info);
+ void setupAndLexVerbatimBlock(Token &T, const char *TextBegin, char Marker,
+ const CommandInfo *Info);
void lexVerbatimBlockFirstLine(Token &T);
@@ -343,14 +347,13 @@ private:
public:
Lexer(llvm::BumpPtrAllocator &Allocator, DiagnosticsEngine &Diags,
- const CommandTraits &Traits,
- SourceLocation FileLoc,
- const char *BufferStart, const char *BufferEnd);
+ const CommandTraits &Traits, SourceLocation FileLoc,
+ const char *BufferStart, const char *BufferEnd,
+ bool ParseCommands = true);
void lex(Token &T);
- StringRef getSpelling(const Token &Tok,
- const SourceManager &SourceMgr,
+ StringRef getSpelling(const Token &Tok, const SourceManager &SourceMgr,
bool *Invalid = nullptr) const;
};
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
index 230e52739f24c..0e94c33970caf 100644
--- a/include/clang/AST/CommentSema.h
+++ b/include/clang/AST/CommentSema.h
@@ -55,7 +55,7 @@ class Sema {
/// Contains a valid value if \c DeclInfo->IsFilled is true.
llvm::StringMap<TParamCommandComment *> TemplateParameterDocs;
- /// AST node for the \\brief command and its aliases.
+ /// AST node for the \command and its aliases.
const BlockCommandComment *BriefCommand;
/// AST node for the \\headerfile command.
@@ -187,7 +187,7 @@ public:
void checkReturnsCommand(const BlockCommandComment *Command);
/// Emit diagnostics about duplicate block commands that should be
- /// used only once per comment, e.g., \\brief and \\returns.
+ /// used only once per comment, e.g., \and \\returns.
void checkBlockCommandDuplicate(const BlockCommandComment *Command);
void checkDeprecatedCommand(const BlockCommandComment *Comment);
diff --git a/include/clang/AST/ComparisonCategories.h b/include/clang/AST/ComparisonCategories.h
new file mode 100644
index 0000000000000..23bfd708e7eb4
--- /dev/null
+++ b/include/clang/AST/ComparisonCategories.h
@@ -0,0 +1,243 @@
+//===- ComparisonCategories.h - Three Way Comparison Data -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Comparison Category enum and data types, which
+// store the types and expressions needed to support operator<=>
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_COMPARISONCATEGORIES_H
+#define LLVM_CLANG_AST_COMPARISONCATEGORIES_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/DenseMap.h"
+#include <array>
+#include <cassert>
+
+namespace llvm {
+ class StringRef;
+ class APSInt;
+}
+
+namespace clang {
+
+class ASTContext;
+class VarDecl;
+class CXXRecordDecl;
+class Sema;
+class QualType;
+class NamespaceDecl;
+
+/// An enumeration representing the different comparison categories
+/// types.
+///
+/// C++2a [cmp.categories.pre] The types weak_equality, strong_equality,
+/// partial_ordering, weak_ordering, and strong_ordering are collectively
+/// termed the comparison category types.
+enum class ComparisonCategoryType : unsigned char {
+ WeakEquality,
+ StrongEquality,
+ PartialOrdering,
+ WeakOrdering,
+ StrongOrdering,
+ First = WeakEquality,
+ Last = StrongOrdering
+};
+
+/// An enumeration representing the possible results of a three-way
+/// comparison. These values map onto instances of comparison category types
+/// defined in the standard library. e.g. 'std::strong_ordering::less'.
+enum class ComparisonCategoryResult : unsigned char {
+ Equal,
+ Equivalent,
+ Nonequivalent,
+ Nonequal,
+ Less,
+ Greater,
+ Unordered,
+ Last = Unordered
+};
+
+class ComparisonCategoryInfo {
+ friend class ComparisonCategories;
+ friend class Sema;
+
+public:
+ ComparisonCategoryInfo(const ASTContext &Ctx, CXXRecordDecl *RD,
+ ComparisonCategoryType Kind)
+ : Ctx(Ctx), Record(RD), Kind(Kind) {}
+
+ struct ValueInfo {
+ ComparisonCategoryResult Kind;
+ VarDecl *VD;
+
+ ValueInfo(ComparisonCategoryResult Kind, VarDecl *VD)
+ : Kind(Kind), VD(VD) {}
+
+ /// True iff we've successfully evaluated the variable as a constant
+ /// expression and extracted its integer value.
+ bool hasValidIntValue() const;
+
+ /// Get the constant integer value used by this variable to represent
+ /// the comparison category result type.
+ llvm::APSInt getIntValue() const;
+ };
+private:
+ const ASTContext &Ctx;
+
+ /// A map containing the comparison category result decls from the
+ /// standard library. The key is a value of ComparisonCategoryResult.
+ mutable llvm::SmallVector<
+ ValueInfo, static_cast<unsigned>(ComparisonCategoryResult::Last) + 1>
+ Objects;
+
+ /// Lookup the ValueInfo struct for the specified ValueKind. If the
+ /// VarDecl for the value cannot be found, nullptr is returned.
+ ///
+ /// If the ValueInfo does not have a valid integer value the variable
+ /// is evaluated as a constant expression to determine that value.
+ ValueInfo *lookupValueInfo(ComparisonCategoryResult ValueKind) const;
+
+public:
+ /// The declaration for the comparison category type from the
+ /// standard library.
+ // FIXME: Make this const
+ CXXRecordDecl *Record = nullptr;
+
+ /// The Kind of the comparison category type
+ ComparisonCategoryType Kind;
+
+public:
+ QualType getType() const;
+
+ const ValueInfo *getValueInfo(ComparisonCategoryResult ValueKind) const {
+ ValueInfo *Info = lookupValueInfo(ValueKind);
+ assert(Info &&
+ "comparison category does not contain the specified result kind");
+ assert(Info->hasValidIntValue() &&
+ "couldn't determine the integer constant for this value");
+ return Info;
+ }
+
+ /// True iff the comparison category is an equality comparison.
+ bool isEquality() const { return !isOrdered(); }
+
+ /// True iff the comparison category is a relational comparison.
+ bool isOrdered() const {
+ using CCK = ComparisonCategoryType;
+ return Kind == CCK::PartialOrdering || Kind == CCK::WeakOrdering ||
+ Kind == CCK::StrongOrdering;
+ }
+
+ /// True iff the comparison is "strong". i.e. it checks equality and
+ /// not equivalence.
+ bool isStrong() const {
+ using CCK = ComparisonCategoryType;
+ return Kind == CCK::StrongEquality || Kind == CCK::StrongOrdering;
+ }
+
+ /// True iff the comparison is not totally ordered.
+ bool isPartial() const {
+ using CCK = ComparisonCategoryType;
+ return Kind == CCK::PartialOrdering;
+ }
+
+ /// Converts the specified result kind into the the correct result kind
+ /// for this category. Specifically it lowers strong equality results to
+ /// weak equivalence if needed.
+ ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const {
+ using CCR = ComparisonCategoryResult;
+ if (!isStrong()) {
+ if (Res == CCR::Equal)
+ return CCR::Equivalent;
+ if (Res == CCR::Nonequal)
+ return CCR::Nonequivalent;
+ }
+ return Res;
+ }
+
+ const ValueInfo *getEqualOrEquiv() const {
+ return getValueInfo(makeWeakResult(ComparisonCategoryResult::Equal));
+ }
+ const ValueInfo *getNonequalOrNonequiv() const {
+ assert(isEquality());
+ return getValueInfo(makeWeakResult(ComparisonCategoryResult::Nonequal));
+ }
+ const ValueInfo *getLess() const {
+ assert(isOrdered());
+ return getValueInfo(ComparisonCategoryResult::Less);
+ }
+ const ValueInfo *getGreater() const {
+ assert(isOrdered());
+ return getValueInfo(ComparisonCategoryResult::Greater);
+ }
+ const ValueInfo *getUnordered() const {
+ assert(isPartial());
+ return getValueInfo(ComparisonCategoryResult::Unordered);
+ }
+};
+
+class ComparisonCategories {
+public:
+ static StringRef getCategoryString(ComparisonCategoryType Kind);
+ static StringRef getResultString(ComparisonCategoryResult Kind);
+
+ /// Return the list of results which are valid for the specified
+ /// comparison category type.
+ static std::vector<ComparisonCategoryResult>
+ getPossibleResultsForType(ComparisonCategoryType Type);
+
+ /// Return the comparison category information for the category
+ /// specified by 'Kind'.
+ const ComparisonCategoryInfo &getInfo(ComparisonCategoryType Kind) const {
+ const ComparisonCategoryInfo *Result = lookupInfo(Kind);
+ assert(Result != nullptr &&
+ "information for specified comparison category has not been built");
+ return *Result;
+ }
+
+ /// Return the comparison category information as specified by
+ /// `getCategoryForType(Ty)`. If the information is not already cached,
+ /// the declaration is looked up and a cache entry is created.
+ /// NOTE: Lookup is expected to succeed. Use lookupInfo if failure is
+ /// possible.
+ const ComparisonCategoryInfo &getInfoForType(QualType Ty) const;
+
+public:
+ /// Return the cached comparison category information for the
+ /// specified 'Kind'. If no cache entry is present the comparison category
+ /// type is looked up. If lookup fails nullptr is returned. Otherwise, a
+ /// new cache entry is created and returned
+ const ComparisonCategoryInfo *lookupInfo(ComparisonCategoryType Kind) const;
+
+ ComparisonCategoryInfo *lookupInfo(ComparisonCategoryType Kind) {
+ const auto &This = *this;
+ return const_cast<ComparisonCategoryInfo *>(This.lookupInfo(Kind));
+ }
+
+private:
+ const ComparisonCategoryInfo *lookupInfoForType(QualType Ty) const;
+
+private:
+ friend class ASTContext;
+
+ explicit ComparisonCategories(const ASTContext &Ctx) : Ctx(Ctx) {}
+
+ const ASTContext &Ctx;
+
+ /// A map from the ComparisonCategoryType (represented as 'char') to the
+ /// cached information for the specified category.
+ mutable llvm::DenseMap<char, ComparisonCategoryInfo> Data;
+ mutable NamespaceDecl *StdNS = nullptr;
+};
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/AST/DataCollection.h b/include/clang/AST/DataCollection.h
index 229ac2bd0f22d..8b2a8345d9415 100644
--- a/include/clang/AST/DataCollection.h
+++ b/include/clang/AST/DataCollection.h
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
/// \file
-/// \brief This file declares helper methods for collecting data from AST nodes.
+/// This file declares helper methods for collecting data from AST nodes.
///
/// To collect data from Stmt nodes, subclass ConstStmtVisitor and include
/// StmtDataCollectors.inc after defining the macros that you need. This
/// provides data collection implementations for most Stmt kinds. Note
-/// that that code requires some conditions to be met:
+/// that the code requires some conditions to be met:
///
/// - There must be a method addData(const T &Data) that accepts strings,
/// integral types as well as QualType. All data is forwarded using
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 04a832e552a4a..dde94599636f0 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -76,14 +76,14 @@ class TypeLoc;
class UnresolvedSetImpl;
class VarTemplateDecl;
-/// \brief A container of type source information.
+/// A container of type source information.
///
/// A client can read the relevant info using TypeLoc wrappers, e.g:
/// @code
/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
/// TL.getStartLoc().print(OS, SrcMgr);
/// @endcode
-class TypeSourceInfo {
+class alignas(8) TypeSourceInfo {
// Contains a memory block after the class, used for type source information,
// allocated by ASTContext.
friend class ASTContext;
@@ -93,17 +93,17 @@ class TypeSourceInfo {
TypeSourceInfo(QualType ty) : Ty(ty) {}
public:
- /// \brief Return the type wrapped by this type source info.
+ /// Return the type wrapped by this type source info.
QualType getType() const { return Ty; }
- /// \brief Return the TypeLoc wrapper for the type source info.
+ /// Return the TypeLoc wrapper for the type source info.
TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
- /// \brief Override the type stored in this TypeSourceInfo. Use with caution!
+ /// Override the type stored in this TypeSourceInfo. Use with caution!
void overrideType(QualType T) { Ty = T; }
};
-/// TranslationUnitDecl - The top declaration context.
+/// The top declaration context.
class TranslationUnitDecl : public Decl, public DeclContext {
ASTContext &Ctx;
@@ -134,7 +134,7 @@ public:
}
};
-/// \brief Represents a `#pragma comment` line. Always a child of
+/// Represents a `#pragma comment` line. Always a child of
/// TranslationUnitDecl.
class PragmaCommentDecl final
: public Decl,
@@ -168,7 +168,7 @@ public:
static bool classofKind(Kind K) { return K == PragmaComment; }
};
-/// \brief Represents a `#pragma detect_mismatch` line. Always a child of
+/// Represents a `#pragma detect_mismatch` line. Always a child of
/// TranslationUnitDecl.
class PragmaDetectMismatchDecl final
: public Decl,
@@ -201,7 +201,7 @@ public:
static bool classofKind(Kind K) { return K == PragmaDetectMismatch; }
};
-/// \brief Declaration context for names declared as extern "C" in C++. This
+/// Declaration context for names declared as extern "C" in C++. This
/// is neither the semantic nor lexical context for such declarations, but is
/// used to check for conflicts with other extern "C" declarations. Example:
///
@@ -240,10 +240,13 @@ public:
}
};
-/// NamedDecl - This represents a decl with a name. Many decls have names such
+/// This represents a decl that may have a name. Many decls have names such
/// as ObjCMethodDecl, but not \@class, etc.
+///
+/// Note that not every NamedDecl is actually named (e.g., a struct might
+/// be anonymous), and not every name is an identifier.
class NamedDecl : public Decl {
- /// Name - The name of this declaration, which is typically a normal
+ /// The name of this declaration, which is typically a normal
/// identifier but may also be a special kind of name (C++
/// constructor, Objective-C selector, etc.)
DeclarationName Name;
@@ -258,13 +261,15 @@ protected:
: Decl(DK, DC, L), Name(N) {}
public:
- /// getIdentifier - Get the identifier that names this declaration,
- /// if there is one. This will return NULL if this declaration has
- /// no name (e.g., for an unnamed class) or if the name is a special
- /// name (C++ constructor, Objective-C selector, etc.).
+ /// Get the identifier that names this declaration, if there is one.
+ ///
+ /// This will return NULL if this declaration has no name (e.g., for
+ /// an unnamed class) or if the name is a special name (C++ constructor,
+ /// Objective-C selector, etc.).
IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); }
- /// getName - Get the name of identifier for this declaration as a StringRef.
+ /// Get the name of identifier for this declaration as a StringRef.
+ ///
/// This requires that the declaration have a name and that it be a simple
/// identifier.
StringRef getName() const {
@@ -272,11 +277,12 @@ public:
return getIdentifier() ? getIdentifier()->getName() : "";
}
- /// getNameAsString - Get a human-readable name for the declaration, even if
- /// it is one of the special kinds of names (C++ constructor, Objective-C
- /// selector, etc). Creating this name requires expensive string
- /// manipulation, so it should be called only when performance doesn't matter.
- /// For simple declarations, getNameAsCString() should suffice.
+ /// Get a human-readable name for the declaration, even if it is one of the
+ /// special kinds of names (C++ constructor, Objective-C selector, etc).
+ ///
+ /// Creating this name requires expensive string manipulation, so it should
+ /// be called only when performance doesn't matter. For simple declarations,
+ /// getNameAsCString() should suffice.
//
// FIXME: This function should be renamed to indicate that it is not just an
// alternate form of getName(), and clients should move as appropriate.
@@ -286,17 +292,19 @@ public:
virtual void printName(raw_ostream &os) const;
- /// getDeclName - Get the actual, stored name of the declaration,
- /// which may be a special name.
+ /// Get the actual, stored name of the declaration, which may be a special
+ /// name.
DeclarationName getDeclName() const { return Name; }
- /// \brief Set the name of this declaration.
+ /// Set the name of this declaration.
void setDeclName(DeclarationName N) { Name = N; }
- /// printQualifiedName - Returns human-readable qualified name for
- /// declaration, like A::B::i, for i being member of namespace A::B.
- /// If declaration is not member of context which can be named (record,
- /// namespace), it will return same result as printName().
+ /// Returns a human-readable qualified name for this declaration, like
+ /// A::B::i, for i being member of namespace A::B.
+ ///
+ /// If the declaration is not a member of context which can be named (record,
+ /// namespace), it will return the same result as printName().
+ ///
/// Creating this name is expensive, so it should be called only when
/// performance doesn't matter.
void printQualifiedName(raw_ostream &OS) const;
@@ -315,25 +323,25 @@ public:
const PrintingPolicy &Policy,
bool Qualified) const;
- /// \brief Determine whether this declaration, if
- /// known to be well-formed within its context, will replace the
- /// declaration OldD if introduced into scope. A declaration will
- /// replace another declaration if, for example, it is a
- /// redeclaration of the same variable or function, but not if it is
- /// a declaration of a different kind (function vs. class) or an
- /// overloaded function.
+ /// Determine whether this declaration, if known to be well-formed within
+ /// its context, will replace the declaration OldD if introduced into scope.
+ ///
+ /// A declaration will replace another declaration if, for example, it is
+ /// a redeclaration of the same variable or function, but not if it is a
+ /// declaration of a different kind (function vs. class) or an overloaded
+ /// function.
///
/// \param IsKnownNewer \c true if this declaration is known to be newer
/// than \p OldD (for instance, if this declaration is newly-created).
bool declarationReplaces(NamedDecl *OldD, bool IsKnownNewer = true) const;
- /// \brief Determine whether this declaration has linkage.
+ /// Determine whether this declaration has linkage.
bool hasLinkage() const;
using Decl::isModulePrivate;
using Decl::setModulePrivate;
- /// \brief Determine whether this declaration is a C++ class member.
+ /// Determine whether this declaration is a C++ class member.
bool isCXXClassMember() const {
const DeclContext *DC = getDeclContext();
@@ -346,23 +354,24 @@ public:
return DC->isRecord();
}
- /// \brief Determine whether the given declaration is an instance member of
+ /// Determine whether the given declaration is an instance member of
/// a C++ class.
bool isCXXInstanceMember() const;
- /// \brief Determine what kind of linkage this entity has.
+ /// Determine what kind of linkage this entity has.
+ ///
/// This is not the linkage as defined by the standard or the codegen notion
/// of linkage. It is just an implementation detail that is used to compute
/// those.
Linkage getLinkageInternal() const;
- /// \brief Get the linkage from a semantic point of view. Entities in
+ /// Get the linkage from a semantic point of view. Entities in
/// anonymous namespaces are external (in c++98).
Linkage getFormalLinkage() const {
return clang::getFormalLinkage(getLinkageInternal());
}
- /// \brief True if this decl has external linkage.
+ /// True if this decl has external linkage.
bool hasExternalFormalLinkage() const {
return isExternalFormalLinkage(getLinkageInternal());
}
@@ -377,12 +386,12 @@ public:
return isExternallyVisible() && !getOwningModuleForLinkage();
}
- /// \brief Determines the visibility of this entity.
+ /// Determines the visibility of this entity.
Visibility getVisibility() const {
return getLinkageAndVisibility().getVisibility();
}
- /// \brief Determines the linkage and visibility of this entity.
+ /// Determines the linkage and visibility of this entity.
LinkageInfo getLinkageAndVisibility() const;
/// Kinds of explicit visibility.
@@ -398,16 +407,16 @@ public:
VisibilityForValue
};
- /// \brief If visibility was explicitly specified for this
+ /// If visibility was explicitly specified for this
/// declaration, return that visibility.
Optional<Visibility>
getExplicitVisibility(ExplicitVisibilityKind kind) const;
- /// \brief True if the computed linkage is valid. Used for consistency
+ /// True if the computed linkage is valid. Used for consistency
/// checking. Should always return true.
bool isLinkageValid() const;
- /// \brief True if something has required us to compute the linkage
+ /// True if something has required us to compute the linkage
/// of this declaration.
///
/// Language features which can retroactively change linkage (like a
@@ -417,7 +426,7 @@ public:
return hasCachedLinkage();
}
- /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
+ /// Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
NamedDecl *getUnderlyingDecl() {
// Fast-path the common case.
@@ -451,7 +460,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) {
return OS;
}
-/// LabelDecl - Represents the declaration of a label. Labels also have a
+/// Represents the declaration of a label. Labels also have a
/// corresponding LabelStmt, which indicates the position that the label was
/// defined at. For normal labels, the location of the decl is the same as the
/// location of the statement. For GNU local labels (__label__), the decl
@@ -461,7 +470,7 @@ class LabelDecl : public NamedDecl {
StringRef MSAsmName;
bool MSAsmNameResolved = false;
- /// LocStart - For normal labels, this is the same as the main declaration
+ /// For normal labels, this is the same as the main declaration
/// label, i.e., the location of the identifier; for GNU local labels,
/// this is the location of the __label__ keyword.
SourceLocation LocStart;
@@ -501,18 +510,18 @@ public:
static bool classofKind(Kind K) { return K == Label; }
};
-/// NamespaceDecl - Represent a C++ namespace.
+/// Represent a C++ namespace.
class NamespaceDecl : public NamedDecl, public DeclContext,
public Redeclarable<NamespaceDecl>
{
- /// LocStart - The starting location of the source range, pointing
+ /// The starting location of the source range, pointing
/// to either the namespace or the inline keyword.
SourceLocation LocStart;
- /// RBraceLoc - The ending location of the source range.
+ /// The ending location of the source range.
SourceLocation RBraceLoc;
- /// \brief A pointer to either the anonymous namespace that lives just inside
+ /// A pointer to either the anonymous namespace that lives just inside
/// this namespace or to the first namespace in the chain (the latter case
/// only when this is not the first in the chain), along with a
/// boolean value indicating whether this is an inline namespace.
@@ -549,7 +558,7 @@ public:
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
- /// \brief Returns true if this is an anonymous namespace declaration.
+ /// Returns true if this is an anonymous namespace declaration.
///
/// For example:
/// \code
@@ -562,28 +571,28 @@ public:
return !getIdentifier();
}
- /// \brief Returns true if this is an inline namespace declaration.
+ /// Returns true if this is an inline namespace declaration.
bool isInline() const {
return AnonOrFirstNamespaceAndInline.getInt();
}
- /// \brief Set whether this is an inline namespace declaration.
+ /// Set whether this is an inline namespace declaration.
void setInline(bool Inline) {
AnonOrFirstNamespaceAndInline.setInt(Inline);
}
- /// \brief Get the original (first) namespace declaration.
+ /// Get the original (first) namespace declaration.
NamespaceDecl *getOriginalNamespace();
- /// \brief Get the original (first) namespace declaration.
+ /// Get the original (first) namespace declaration.
const NamespaceDecl *getOriginalNamespace() const;
- /// \brief Return true if this declaration is an original (first) declaration
+ /// Return true if this declaration is an original (first) declaration
/// of the namespace. This is false for non-original (subsequent) namespace
/// declarations and anonymous namespaces.
bool isOriginalNamespace() const;
- /// \brief Retrieve the anonymous namespace nested inside this namespace,
+ /// Retrieve the anonymous namespace nested inside this namespace,
/// if any.
NamespaceDecl *getAnonymousNamespace() const {
return getOriginalNamespace()->AnonOrFirstNamespaceAndInline.getPointer();
@@ -621,7 +630,7 @@ public:
}
};
-/// ValueDecl - Represent the declaration of a variable (in which case it is
+/// Represent the declaration of a variable (in which case it is
/// an lvalue) a function (in which case it is a function designator) or
/// an enum constant.
class ValueDecl : public NamedDecl {
@@ -638,7 +647,7 @@ public:
QualType getType() const { return DeclType; }
void setType(QualType newType) { DeclType = newType; }
- /// \brief Determine whether this symbol is weakly-imported,
+ /// Determine whether this symbol is weakly-imported,
/// or declared with the weak or weak-ref attr.
bool isWeak() const;
@@ -647,18 +656,18 @@ public:
static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
};
-/// QualifierInfo - A struct with extended info about a syntactic
+/// A struct with extended info about a syntactic
/// name qualifier, to be used for the case of out-of-line declarations.
struct QualifierInfo {
NestedNameSpecifierLoc QualifierLoc;
- /// NumTemplParamLists - The number of "outer" template parameter lists.
+ /// The number of "outer" template parameter lists.
/// The count includes all of the template parameter lists that were matched
/// against the template-ids occurring into the NNS and possibly (in the
/// case of an explicit specialization) a final "template <>".
unsigned NumTemplParamLists = 0;
- /// TemplParamLists - A new-allocated array of size NumTemplParamLists,
+ /// A new-allocated array of size NumTemplParamLists,
/// containing pointers to the "outer" template parameter lists.
/// It includes all of the template parameter lists that were matched
/// against the template-ids occurring into the NNS and possibly (in the
@@ -669,13 +678,12 @@ struct QualifierInfo {
QualifierInfo(const QualifierInfo &) = delete;
QualifierInfo& operator=(const QualifierInfo &) = delete;
- /// setTemplateParameterListsInfo - Sets info about "outer" template
- /// parameter lists.
+ /// Sets info about "outer" template parameter lists.
void setTemplateParameterListsInfo(ASTContext &Context,
ArrayRef<TemplateParameterList *> TPLists);
};
-/// \brief Represents a ValueDecl that came out of a declarator.
+/// Represents a ValueDecl that came out of a declarator.
/// Contains type source information through TypeSourceInfo.
class DeclaratorDecl : public ValueDecl {
// A struct representing both a TInfo and a syntactic qualifier,
@@ -686,7 +694,7 @@ class DeclaratorDecl : public ValueDecl {
llvm::PointerUnion<TypeSourceInfo *, ExtInfo *> DeclInfo;
- /// InnerLocStart - The start of the source range for this declaration,
+ /// The start of the source range for this declaration,
/// ignoring outer template declarations.
SourceLocation InnerLocStart;
@@ -717,13 +725,12 @@ public:
DeclInfo = TI;
}
- /// getInnerLocStart - Return SourceLocation representing start of source
- /// range ignoring outer template declarations.
+ /// Return start of source range ignoring outer template declarations.
SourceLocation getInnerLocStart() const { return InnerLocStart; }
void setInnerLocStart(SourceLocation L) { InnerLocStart = L; }
- /// getOuterLocStart - Return SourceLocation representing start of source
- /// range taking into account any outer template declarations.
+ /// Return start of source range taking into account any outer template
+ /// declarations.
SourceLocation getOuterLocStart() const;
SourceRange getSourceRange() const override LLVM_READONLY;
@@ -732,14 +739,14 @@ public:
return getOuterLocStart();
}
- /// \brief Retrieve the nested-name-specifier that qualifies the name of this
+ /// Retrieve the nested-name-specifier that qualifies the name of this
/// declaration, if it was present in the source.
NestedNameSpecifier *getQualifier() const {
return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
: nullptr;
}
- /// \brief Retrieve the nested-name-specifier (with source-location
+ /// Retrieve the nested-name-specifier (with source-location
/// information) that qualifies the name of this declaration, if it was
/// present in the source.
NestedNameSpecifierLoc getQualifierLoc() const {
@@ -770,25 +777,25 @@ public:
}
};
-/// \brief Structure used to store a statement, the constant value to
+/// Structure used to store a statement, the constant value to
/// which it was evaluated (if any), and whether or not the statement
/// is an integral constant expression (if known).
struct EvaluatedStmt {
- /// \brief Whether this statement was already evaluated.
+ /// Whether this statement was already evaluated.
bool WasEvaluated : 1;
- /// \brief Whether this statement is being evaluated.
+ /// Whether this statement is being evaluated.
bool IsEvaluating : 1;
- /// \brief Whether we already checked whether this statement was an
+ /// Whether we already checked whether this statement was an
/// integral constant expression.
bool CheckedICE : 1;
- /// \brief Whether we are checking whether this statement is an
+ /// Whether we are checking whether this statement is an
/// integral constant expression.
bool CheckingICE : 1;
- /// \brief Whether this statement is an integral constant expression,
+ /// Whether this statement is an integral constant expression,
/// or in C++11, whether the statement is a constant expression. Only
/// valid if CheckedICE is true.
bool IsICE : 1;
@@ -801,11 +808,10 @@ struct EvaluatedStmt {
};
-/// VarDecl - An instance of this class is created to represent a variable
-/// declaration or definition.
+/// Represents a variable declaration or definition.
class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
public:
- /// \brief Initialization styles.
+ /// Initialization styles.
enum InitializationStyle {
/// C-style initialization with assignment
CInit,
@@ -817,7 +823,7 @@ public:
ListInit
};
- /// \brief Kinds of thread-local storage.
+ /// Kinds of thread-local storage.
enum TLSKind {
/// Not a TLS variable.
TLS_None,
@@ -829,8 +835,7 @@ public:
TLS_Dynamic
};
- /// getStorageClassSpecifierString - Return the string used to
- /// specify the storage class \p SC.
+ /// Return the string used to specify the storage class \p SC.
///
/// It is illegal to call this function with SC == None.
static const char *getStorageClassSpecifierString(StorageClass SC);
@@ -845,7 +850,7 @@ protected:
// allocated in trailing space when necessary.
using InitType = llvm::PointerUnion<Stmt *, EvaluatedStmt *>;
- /// \brief The initializer for this variable or, for a ParmVarDecl, the
+ /// The initializer for this variable or, for a ParmVarDecl, the
/// C++ default argument.
mutable InitType Init;
@@ -915,41 +920,44 @@ protected:
unsigned : NumVarDeclBits;
// FIXME: We need something similar to CXXRecordDecl::DefinitionData.
- /// \brief Whether this variable is a definition which was demoted due to
+ /// Whether this variable is a definition which was demoted due to
/// module merge.
unsigned IsThisDeclarationADemotedDefinition : 1;
- /// \brief Whether this variable is the exception variable in a C++ catch
+ /// Whether this variable is the exception variable in a C++ catch
/// or an Objective-C @catch statement.
unsigned ExceptionVar : 1;
- /// \brief Whether this local variable could be allocated in the return
+ /// Whether this local variable could be allocated in the return
/// slot of its function, enabling the named return value optimization
/// (NRVO).
unsigned NRVOVariable : 1;
- /// \brief Whether this variable is the for-range-declaration in a C++0x
+ /// Whether this variable is the for-range-declaration in a C++0x
/// for-range statement.
unsigned CXXForRangeDecl : 1;
- /// \brief Whether this variable is an ARC pseudo-__strong
+ /// Whether this variable is the for-in loop declaration in Objective-C.
+ unsigned ObjCForDecl : 1;
+
+ /// Whether this variable is an ARC pseudo-__strong
/// variable; see isARCPseudoStrong() for details.
unsigned ARCPseudoStrong : 1;
- /// \brief Whether this variable is (C++1z) inline.
+ /// Whether this variable is (C++1z) inline.
unsigned IsInline : 1;
- /// \brief Whether this variable has (C++1z) inline explicitly specified.
+ /// Whether this variable has (C++1z) inline explicitly specified.
unsigned IsInlineSpecified : 1;
- /// \brief Whether this variable is (C++0x) constexpr.
+ /// Whether this variable is (C++0x) constexpr.
unsigned IsConstexpr : 1;
- /// \brief Whether this variable is the implicit variable for a lambda
+ /// Whether this variable is the implicit variable for a lambda
/// init-capture.
unsigned IsInitCapture : 1;
- /// \brief Whether this local extern variable's previous declaration was
+ /// Whether this local extern variable's previous declaration was
/// declared in the same block scope. This controls whether we should merge
/// the type of this declaration with its previous declaration.
unsigned PreviousDeclInSameBlockScope : 1;
@@ -1004,7 +1012,7 @@ public:
SourceRange getSourceRange() const override LLVM_READONLY;
- /// \brief Returns the storage class as written in the source. For the
+ /// Returns the storage class as written in the source. For the
/// computed linkage of symbol, see getLinkage.
StorageClass getStorageClass() const {
return (StorageClass) VarDeclBits.SClass;
@@ -1020,8 +1028,8 @@ public:
}
TLSKind getTLSKind() const;
- /// hasLocalStorage - Returns true if a variable with function scope
- /// is a non-static local variable.
+ /// Returns true if a variable with function scope is a non-static local
+ /// variable.
bool hasLocalStorage() const {
if (getStorageClass() == SC_None) {
// OpenCL v1.2 s6.5.3: The __constant or constant address space name is
@@ -1044,8 +1052,8 @@ public:
return getStorageClass() >= SC_Auto;
}
- /// isStaticLocal - Returns true if a variable with function scope is a
- /// static local variable.
+ /// Returns true if a variable with function scope is a static local
+ /// variable.
bool isStaticLocal() const {
return (getStorageClass() == SC_Static ||
// C++11 [dcl.stc]p4
@@ -1053,43 +1061,42 @@ public:
&& !isFileVarDecl();
}
- /// \brief Returns true if a variable has extern or __private_extern__
+ /// Returns true if a variable has extern or __private_extern__
/// storage.
bool hasExternalStorage() const {
return getStorageClass() == SC_Extern ||
getStorageClass() == SC_PrivateExtern;
}
- /// \brief Returns true for all variables that do not have local storage.
+ /// Returns true for all variables that do not have local storage.
///
/// This includes all global variables as well as static variables declared
/// within a function.
bool hasGlobalStorage() const { return !hasLocalStorage(); }
- /// \brief Get the storage duration of this variable, per C++ [basic.stc].
+ /// Get the storage duration of this variable, per C++ [basic.stc].
StorageDuration getStorageDuration() const {
return hasLocalStorage() ? SD_Automatic :
getTSCSpec() ? SD_Thread : SD_Static;
}
- /// \brief Compute the language linkage.
+ /// Compute the language linkage.
LanguageLinkage getLanguageLinkage() const;
- /// \brief Determines whether this variable is a variable with
- /// external, C linkage.
+ /// Determines whether this variable is a variable with external, C linkage.
bool isExternC() const;
- /// \brief Determines whether this variable's context is, or is nested within,
+ /// Determines whether this variable's context is, or is nested within,
/// a C++ extern "C" linkage spec.
bool isInExternCContext() const;
- /// \brief Determines whether this variable's context is, or is nested within,
+ /// Determines whether this variable's context is, or is nested within,
/// a C++ extern "C++" linkage spec.
bool isInExternCXXContext() const;
- /// isLocalVarDecl - Returns true for local variable declarations
- /// other than parameters. Note that this includes static variables
- /// inside of functions. It also includes variables inside blocks.
+ /// Returns true for local variable declarations other than parameters.
+ /// Note that this includes static variables inside of functions. It also
+ /// includes variables inside blocks.
///
/// void foo() { int x; static int y; extern int z; }
bool isLocalVarDecl() const {
@@ -1100,13 +1107,12 @@ public:
return false;
}
- /// \brief Similar to isLocalVarDecl but also includes parameters.
+ /// Similar to isLocalVarDecl but also includes parameters.
bool isLocalVarDeclOrParm() const {
return isLocalVarDecl() || getKind() == Decl::ParmVar;
}
- /// isFunctionOrMethodVarDecl - Similar to isLocalVarDecl, but
- /// excludes variables declared in blocks.
+ /// Similar to isLocalVarDecl, but excludes variables declared in blocks.
bool isFunctionOrMethodVarDecl() const {
if (getKind() != Decl::Var && getKind() != Decl::Decomposition)
return false;
@@ -1114,7 +1120,7 @@ public:
return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;
}
- /// \brief Determines whether this is a static data member.
+ /// Determines whether this is a static data member.
///
/// This will only be true in C++, and applies to, e.g., the
/// variable 'x' in:
@@ -1144,7 +1150,7 @@ public:
Definition
};
- /// \brief Check whether this declaration is a definition. If this could be
+ /// Check whether this declaration is a definition. If this could be
/// a tentative definition (in C), don't check whether there's an overriding
/// definition.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const;
@@ -1152,21 +1158,20 @@ public:
return isThisDeclarationADefinition(getASTContext());
}
- /// \brief Check whether this variable is defined in this
- /// translation unit.
+ /// Check whether this variable is defined in this translation unit.
DefinitionKind hasDefinition(ASTContext &) const;
DefinitionKind hasDefinition() const {
return hasDefinition(getASTContext());
}
- /// \brief Get the tentative definition that acts as the real definition in
- /// a TU. Returns null if there is a proper definition available.
+ /// Get the tentative definition that acts as the real definition in a TU.
+ /// Returns null if there is a proper definition available.
VarDecl *getActingDefinition();
const VarDecl *getActingDefinition() const {
return const_cast<VarDecl*>(this)->getActingDefinition();
}
- /// \brief Get the real (not just tentative) definition for this declaration.
+ /// Get the real (not just tentative) definition for this declaration.
VarDecl *getDefinition(ASTContext &);
const VarDecl *getDefinition(ASTContext &C) const {
return const_cast<VarDecl*>(this)->getDefinition(C);
@@ -1178,11 +1183,11 @@ public:
return const_cast<VarDecl*>(this)->getDefinition();
}
- /// \brief Determine whether this is or was instantiated from an out-of-line
+ /// Determine whether this is or was instantiated from an out-of-line
/// definition of a static data member.
bool isOutOfLine() const override;
- /// isFileVarDecl - Returns true for file scoped variable declaration.
+ /// Returns true for file scoped variable declaration.
bool isFileVarDecl() const {
Kind K = getKind();
if (K == ParmVar || K == ImplicitParam)
@@ -1197,14 +1202,14 @@ public:
return false;
}
- /// getAnyInitializer - Get the initializer for this variable, no matter which
+ /// Get the initializer for this variable, no matter which
/// declaration it is attached to.
const Expr *getAnyInitializer() const {
const VarDecl *D;
return getAnyInitializer(D);
}
- /// getAnyInitializer - Get the initializer for this variable, no matter which
+ /// Get the initializer for this variable, no matter which
/// declaration it is attached to. Also get that declaration.
const Expr *getAnyInitializer(const VarDecl *&D) const;
@@ -1214,12 +1219,12 @@ public:
}
Expr *getInit();
- /// \brief Retrieve the address of the initializer expression.
+ /// Retrieve the address of the initializer expression.
Stmt **getInitAddress();
void setInit(Expr *I);
- /// \brief Determine whether this variable's value can be used in a
+ /// Determine whether this variable's value can be used in a
/// constant expression, according to the relevant language standard.
/// This only checks properties of the declaration, and does not check
/// whether the initializer is in fact a constant expression.
@@ -1227,30 +1232,30 @@ public:
EvaluatedStmt *ensureEvaluatedStmt() const;
- /// \brief Attempt to evaluate the value of the initializer attached to this
+ /// Attempt to evaluate the value of the initializer attached to this
/// declaration, and produce notes explaining why it cannot be evaluated or is
/// not a constant expression. Returns a pointer to the value if evaluation
/// succeeded, 0 otherwise.
APValue *evaluateValue() const;
APValue *evaluateValue(SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
- /// \brief Return the already-evaluated value of this variable's
+ /// Return the already-evaluated value of this variable's
/// initializer, or NULL if the value is not yet known. Returns pointer
/// to untyped APValue if the value could not be evaluated.
APValue *getEvaluatedValue() const;
- /// \brief Determines whether it is already known whether the
+ /// Determines whether it is already known whether the
/// initializer is an integral constant expression or not.
bool isInitKnownICE() const;
- /// \brief Determines whether the initializer is an integral constant
+ /// Determines whether the initializer is an integral constant
/// expression, or in C++11, whether the initializer is a constant
/// expression.
///
/// \pre isInitKnownICE()
bool isInitICE() const;
- /// \brief Determine whether the value of the initializer attached to this
+ /// Determine whether the value of the initializer attached to this
/// declaration is an integral constant expression.
bool checkInitIsICE() const;
@@ -1258,7 +1263,7 @@ public:
VarDeclBits.InitStyle = Style;
}
- /// \brief The style of initialization for this declaration.
+ /// The style of initialization for this declaration.
///
/// C-style initialization is "int x = 1;". Call-style initialization is
/// a C++98 direct-initializer, e.g. "int x(1);". The Init expression will be
@@ -1272,18 +1277,18 @@ public:
return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
}
- /// \brief Whether the initializer is a direct-initializer (list or call).
+ /// Whether the initializer is a direct-initializer (list or call).
bool isDirectInit() const {
return getInitStyle() != CInit;
}
- /// \brief If this definition should pretend to be a declaration.
+ /// If this definition should pretend to be a declaration.
bool isThisDeclarationADemotedDefinition() const {
return isa<ParmVarDecl>(this) ? false :
NonParmVarDeclBits.IsThisDeclarationADemotedDefinition;
}
- /// \brief This is a definition which should be demoted to a declaration.
+ /// This is a definition which should be demoted to a declaration.
///
/// In some cases (mostly module merging) we can end up with two visible
/// definitions one of which needs to be demoted to a declaration to keep
@@ -1294,7 +1299,7 @@ public:
NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = 1;
}
- /// \brief Determine whether this variable is the exception variable in a
+ /// Determine whether this variable is the exception variable in a
/// C++ catch statememt or an Objective-C \@catch statement.
bool isExceptionVariable() const {
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ExceptionVar;
@@ -1304,7 +1309,7 @@ public:
NonParmVarDeclBits.ExceptionVar = EV;
}
- /// \brief Determine whether this local variable can be used with the named
+ /// Determine whether this local variable can be used with the named
/// return value optimization (NRVO).
///
/// The named return value optimization (NRVO) works by marking certain
@@ -1322,7 +1327,7 @@ public:
NonParmVarDeclBits.NRVOVariable = NRVO;
}
- /// \brief Determine whether this variable is the for-range-declaration in
+ /// Determine whether this variable is the for-range-declaration in
/// a C++0x for-range statement.
bool isCXXForRangeDecl() const {
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.CXXForRangeDecl;
@@ -1332,7 +1337,17 @@ public:
NonParmVarDeclBits.CXXForRangeDecl = FRD;
}
- /// \brief Determine whether this variable is an ARC pseudo-__strong
+ /// Determine whether this variable is a for-loop declaration for a
+ /// for-in statement in Objective-C.
+ bool isObjCForDecl() const {
+ return NonParmVarDeclBits.ObjCForDecl;
+ }
+
+ void setObjCForDecl(bool FRD) {
+ NonParmVarDeclBits.ObjCForDecl = FRD;
+ }
+
+ /// Determine whether this variable is an ARC pseudo-__strong
/// variable. A pseudo-__strong variable has a __strong-qualified
/// type but does not actually retain the object written into it.
/// Generally such variables are also 'const' for safety.
@@ -1392,41 +1407,41 @@ public:
NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same;
}
- /// \brief Retrieve the variable declaration from which this variable could
+ /// Retrieve the variable declaration from which this variable could
/// be instantiated, if it is an instantiation (rather than a non-template).
VarDecl *getTemplateInstantiationPattern() const;
- /// \brief If this variable is an instantiated static data member of a
+ /// If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
/// from which it was instantiated.
VarDecl *getInstantiatedFromStaticDataMember() const;
- /// \brief If this variable is an instantiation of a variable template or a
+ /// If this variable is an instantiation of a variable template or a
/// static data member of a class template, determine what kind of
/// template specialization or instantiation this is.
TemplateSpecializationKind getTemplateSpecializationKind() const;
- /// \brief If this variable is an instantiation of a variable template or a
+ /// If this variable is an instantiation of a variable template or a
/// static data member of a class template, determine its point of
/// instantiation.
SourceLocation getPointOfInstantiation() const;
- /// \brief If this variable is an instantiation of a static data member of a
+ /// If this variable is an instantiation of a static data member of a
/// class template specialization, retrieves the member specialization
/// information.
MemberSpecializationInfo *getMemberSpecializationInfo() const;
- /// \brief For a static data member that was instantiated from a static
+ /// For a static data member that was instantiated from a static
/// data member of a class template, set the template specialiation kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());
- /// \brief Specify that this variable is an instantiation of the
+ /// Specify that this variable is an instantiation of the
/// static data member VD.
void setInstantiationOfStaticDataMember(VarDecl *VD,
TemplateSpecializationKind TSK);
- /// \brief Retrieves the variable template that is described by this
+ /// Retrieves the variable template that is described by this
/// variable declaration.
///
/// Every variable template is represented as a VarTemplateDecl and a
@@ -1441,6 +1456,11 @@ public:
void setDescribedVarTemplate(VarTemplateDecl *Template);
+ // Is this variable known to have a definition somewhere in the complete
+ // program? This may be true even if the declaration has internal linkage and
+ // has no definition within this source file.
+ bool isKnownToBeDefined() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
@@ -1509,7 +1529,7 @@ public:
static bool classofKind(Kind K) { return K == ImplicitParam; }
};
-/// ParmVarDecl - Represents a parameter to a function.
+/// Represents a parameter to a function.
class ParmVarDecl : public VarDecl {
public:
enum { MaxFunctionScopeDepth = 255 };
@@ -1598,7 +1618,7 @@ public:
void setDefaultArg(Expr *defarg);
- /// \brief Retrieve the source range that covers the entire default
+ /// Retrieve the source range that covers the entire default
/// argument.
SourceRange getDefaultArgRange() const;
void setUninstantiatedDefaultArg(Expr *arg);
@@ -1607,14 +1627,13 @@ public:
return const_cast<ParmVarDecl *>(this)->getUninstantiatedDefaultArg();
}
- /// hasDefaultArg - Determines whether this parameter has a default argument,
+ /// Determines whether this parameter has a default argument,
/// either parsed or not.
bool hasDefaultArg() const;
- /// hasUnparsedDefaultArg - Determines whether this parameter has a
- /// default argument that has not yet been parsed. This will occur
- /// during the processing of a C++ class whose member functions have
- /// default arguments, e.g.,
+ /// Determines whether this parameter has a default argument that has not
+ /// yet been parsed. This will occur during the processing of a C++ class
+ /// whose member functions have default arguments, e.g.,
/// @code
/// class X {
/// public:
@@ -1629,11 +1648,10 @@ public:
return ParmVarDeclBits.DefaultArgKind == DAK_Uninstantiated;
}
- /// setUnparsedDefaultArg - Specify that this parameter has an
- /// unparsed default argument. The argument will be replaced with a
- /// real default argument via setDefaultArg when the class
- /// definition enclosing the function declaration that owns this
- /// default argument is completed.
+ /// Specify that this parameter has an unparsed default argument.
+ /// The argument will be replaced with a real default argument via
+ /// setDefaultArg when the class definition enclosing the function
+ /// declaration that owns this default argument is completed.
void setUnparsedDefaultArg() {
ParmVarDeclBits.DefaultArgKind = DAK_Unparsed;
}
@@ -1648,11 +1666,11 @@ public:
QualType getOriginalType() const;
- /// \brief Determine whether this parameter is actually a function
+ /// Determine whether this parameter is actually a function
/// parameter pack.
bool isParameterPack() const;
- /// setOwningFunction - Sets the function declaration that owns this
+ /// Sets the function declaration that owns this
/// ParmVarDecl. Since ParmVarDecls are often created before the
/// FunctionDecls that own them, this routine is required to update
/// the DeclContext appropriately.
@@ -1683,8 +1701,7 @@ private:
unsigned getParameterIndexLarge() const;
};
-/// An instance of this class is created to represent a function declaration or
-/// definition.
+/// Represents a function declaration or definition.
///
/// Since a given function can be declared several times in a program,
/// there may be several FunctionDecls that correspond to that
@@ -1697,7 +1714,7 @@ private:
class FunctionDecl : public DeclaratorDecl, public DeclContext,
public Redeclarable<FunctionDecl> {
public:
- /// \brief The kind of templated function a FunctionDecl can be.
+ /// The kind of templated function a FunctionDecl can be.
enum TemplatedKind {
TK_NonTemplate,
TK_FunctionTemplate,
@@ -1707,7 +1724,7 @@ public:
};
private:
- /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
+ /// A new[]'d array of pointers to VarDecls for the formal
/// parameters of this function. This is null if a prototype or if there are
/// no formals.
ParmVarDecl **ParamInfo = nullptr;
@@ -1732,6 +1749,12 @@ private:
unsigned HasWrittenPrototype : 1;
unsigned IsDeleted : 1;
unsigned IsTrivial : 1; // sunk from CXXMethodDecl
+
+ /// This flag indicates whether this function is trivial for the purpose of
+ /// calls. This is meaningful only when this function is a copy/move
+ /// constructor or a destructor.
+ unsigned IsTrivialForCall : 1;
+
unsigned IsDefaulted : 1; // sunk from CXXMethoDecl
unsigned IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl
unsigned HasImplicitReturnZero : 1;
@@ -1739,10 +1762,10 @@ private:
unsigned IsConstexpr : 1;
unsigned InstantiationIsPending : 1;
- /// \brief Indicates if the function uses __try.
+ /// Indicates if the function uses __try.
unsigned UsesSEHTry : 1;
- /// \brief Indicates if the function was a definition but its body was
+ /// Indicates if the function was a definition but its body was
/// skipped.
unsigned HasSkippedBody : 1;
@@ -1750,6 +1773,10 @@ private:
/// parsing it.
unsigned WillHaveBody : 1;
+ /// Indicates that this function is a multiversioned function using attribute
+ /// 'target'.
+ unsigned IsMultiVersion : 1;
+
protected:
/// [C++17] Only used by CXXDeductionGuideDecl. Declared here to avoid
/// increasing the size of CXXDeductionGuideDecl by the size of an unsigned
@@ -1764,7 +1791,7 @@ private:
unsigned HasODRHash : 1;
unsigned ODRHash;
- /// \brief End part of this FunctionDecl's source range.
+ /// End part of this FunctionDecl's source range.
///
/// We could compute the full range in getSourceRange(). However, when we're
/// dealing with a function definition deserialized from a PCH/AST file,
@@ -1773,7 +1800,7 @@ private:
/// EndRangeLoc.
SourceLocation EndRangeLoc;
- /// \brief The template or declaration that this declaration
+ /// The template or declaration that this declaration
/// describes or was instantiated from, respectively.
///
/// For non-templates, this value will be NULL. For function
@@ -1795,7 +1822,7 @@ private:
/// the DeclaratorDecl base class.
DeclarationNameLoc DNLoc;
- /// \brief Specify that this function declaration is actually a function
+ /// Specify that this function declaration is actually a function
/// template specialization.
///
/// \param C the ASTContext.
@@ -1824,7 +1851,7 @@ private:
const TemplateArgumentListInfo *TemplateArgsAsWritten,
SourceLocation PointOfInstantiation);
- /// \brief Specify that this record is an instantiation of the
+ /// Specify that this record is an instantiation of the
/// member function FD.
void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD,
TemplateSpecializationKind TSK);
@@ -1842,13 +1869,14 @@ protected:
IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
IsExplicitSpecified(false), IsVirtualAsWritten(false), IsPure(false),
HasInheritedPrototype(false), HasWrittenPrototype(true),
- IsDeleted(false), IsTrivial(false), IsDefaulted(false),
+ IsDeleted(false), IsTrivial(false), IsTrivialForCall(false),
+ IsDefaulted(false),
IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
InstantiationIsPending(false), UsesSEHTry(false), HasSkippedBody(false),
- WillHaveBody(false), IsCopyDeductionCandidate(false), HasODRHash(false),
- ODRHash(0), EndRangeLoc(NameInfo.getEndLoc()),
- DNLoc(NameInfo.getInfo()) {}
+ WillHaveBody(false), IsMultiVersion(false),
+ IsCopyDeductionCandidate(false), HasODRHash(false), ODRHash(0),
+ EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) {}
using redeclarable_base = Redeclarable<FunctionDecl>;
@@ -1915,11 +1943,25 @@ public:
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
- /// function. The variant that accepts a FunctionDecl pointer will
- /// set that function declaration to the actual declaration
- /// containing the body (if there is one).
+ // Function definitions.
+ //
+ // A function declaration may be:
+ // - a non defining declaration,
+ // - a definition. A function may be defined because:
+ // - it has a body, or will have it in the case of late parsing.
+ // - it has an uninstantiated body. The body does not exist because the
+ // function is not used yet, but the declaration is considered a
+ // definition and does not allow other definition of this function.
+ // - it does not have a user specified body, but it does not allow
+ // redefinition, because it is deleted/defaulted or is defined through
+ // some other mechanism (alias, ifunc).
+
+ /// Returns true if the function has a body.
+ ///
+ /// The function body might be in any of the (re-)declarations of this
+ /// function. The variant that accepts a FunctionDecl pointer will set that
+ /// function declaration to the actual declaration containing the body (if
+ /// there is one).
bool hasBody(const FunctionDecl *&Definition) const;
bool hasBody() const override {
@@ -1931,9 +1973,11 @@ public:
/// specific codegen.
bool hasTrivialBody() const;
- /// Returns true if the function is defined at all, including a deleted
- /// definition. Except for the behavior when the function is deleted, behaves
- /// like hasBody.
+ /// Returns true if the function has a definition that does not need to be
+ /// instantiated.
+ ///
+ /// The variant that accepts a FunctionDecl pointer will set that function
+ /// declaration to the declaration that is a definition (if there is one).
bool isDefined(const FunctionDecl *&Definition) const;
virtual bool isDefined() const {
@@ -1941,7 +1985,7 @@ public:
return isDefined(Definition);
}
- /// \brief Get the definition for this declaration.
+ /// Get the definition for this declaration.
FunctionDecl *getDefinition() {
const FunctionDecl *Definition;
if (isDefined(Definition))
@@ -1975,8 +2019,7 @@ public:
IsLateTemplateParsed || WillHaveBody || hasDefiningAttr();
}
- /// Returns whether this specific declaration of the function has a body -
- /// that is, if it is a non-deleted definition.
+ /// Returns whether this specific declaration of the function has a body.
bool doesThisDeclarationHaveABody() const {
return Body || IsLateTemplateParsed;
}
@@ -2007,6 +2050,9 @@ public:
bool isTrivial() const { return IsTrivial; }
void setTrivial(bool IT) { IsTrivial = IT; }
+ bool isTrivialForCall() const { return IsTrivialForCall; }
+ void setTrivialForCall(bool IT) { IsTrivialForCall = IT; }
+
/// Whether this function is defaulted per C++0x. Only valid for
/// special member functions.
bool isDefaulted() const { return IsDefaulted; }
@@ -2023,7 +2069,7 @@ public:
bool hasImplicitReturnZero() const { return HasImplicitReturnZero; }
void setHasImplicitReturnZero(bool IRZ) { HasImplicitReturnZero = IRZ; }
- /// \brief Whether this function has a prototype, either because one
+ /// Whether this function has a prototype, either because one
/// was explicitly written or because it was "inherited" by merging
/// a declaration without a prototype with a declaration that has a
/// prototype.
@@ -2033,7 +2079,7 @@ public:
bool hasWrittenPrototype() const { return HasWrittenPrototype; }
- /// \brief Whether this function inherited its prototype from a
+ /// Whether this function inherited its prototype from a
/// previous declaration.
bool hasInheritedPrototype() const { return HasInheritedPrototype; }
void setHasInheritedPrototype(bool P = true) { HasInheritedPrototype = P; }
@@ -2042,7 +2088,7 @@ public:
bool isConstexpr() const { return IsConstexpr; }
void setConstexpr(bool IC) { IsConstexpr = IC; }
- /// \brief Whether the instantiation of this function is pending.
+ /// Whether the instantiation of this function is pending.
/// This bit is set when the decision to instantiate this function is made
/// and unset if and when the function body is created. That leaves out
/// cases where instantiation did not happen because the template definition
@@ -2051,11 +2097,11 @@ public:
bool instantiationIsPending() const { return InstantiationIsPending; }
void setInstantiationIsPending(bool IC) { InstantiationIsPending = IC; }
- /// \brief Indicates the function uses __try.
+ /// Indicates the function uses __try.
bool usesSEHTry() const { return UsesSEHTry; }
void setUsesSEHTry(bool UST) { UsesSEHTry = UST; }
- /// \brief Whether this function has been deleted.
+ /// Whether this function has been deleted.
///
/// A function that is "deleted" (via the C++0x "= delete" syntax)
/// acts like a normal function, except that it cannot actually be
@@ -2078,15 +2124,15 @@ public:
bool isDeletedAsWritten() const { return IsDeleted && !IsDefaulted; }
void setDeletedAsWritten(bool D = true) { IsDeleted = D; }
- /// \brief Determines whether this function is "main", which is the
+ /// Determines whether this function is "main", which is the
/// entry point into an executable program.
bool isMain() const;
- /// \brief Determines whether this function is a MSVCRT user defined entry
+ /// Determines whether this function is a MSVCRT user defined entry
/// point.
bool isMSVCRTEntryPoint() const;
- /// \brief Determines whether this operator new or delete is one
+ /// Determines whether this operator new or delete is one
/// of the reserved global placement operators:
/// void *operator new(size_t, void *);
/// void *operator new[](size_t, void *);
@@ -2101,7 +2147,7 @@ public:
/// This function must be an allocation or deallocation function.
bool isReservedGlobalPlacementOperator() const;
- /// \brief Determines whether this function is one of the replaceable
+ /// Determines whether this function is one of the replaceable
/// global allocation functions:
/// void *operator new(size_t);
/// void *operator new(size_t, const std::nothrow_t &) noexcept;
@@ -2121,32 +2167,32 @@ public:
/// true through IsAligned.
bool isReplaceableGlobalAllocationFunction(bool *IsAligned = nullptr) const;
- /// \brief Determine whether this is a destroying operator delete.
+ /// Determine whether this is a destroying operator delete.
bool isDestroyingOperatorDelete() const;
/// Compute the language linkage.
LanguageLinkage getLanguageLinkage() const;
- /// \brief Determines whether this function is a function with
+ /// Determines whether this function is a function with
/// external, C linkage.
bool isExternC() const;
- /// \brief Determines whether this function's context is, or is nested within,
+ /// Determines whether this function's context is, or is nested within,
/// a C++ extern "C" linkage spec.
bool isInExternCContext() const;
- /// \brief Determines whether this function's context is, or is nested within,
+ /// Determines whether this function's context is, or is nested within,
/// a C++ extern "C++" linkage spec.
bool isInExternCXXContext() const;
- /// \brief Determines whether this is a global function.
+ /// Determines whether this is a global function.
bool isGlobal() const;
- /// \brief Determines whether this function is known to be 'noreturn', through
+ /// Determines whether this function is known to be 'noreturn', through
/// an attribute on its declaration or its type.
bool isNoReturn() const;
- /// \brief True if the function was a definition but its body was skipped.
+ /// True if the function was a definition but its body was skipped.
bool hasSkippedBody() const { return HasSkippedBody; }
void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
@@ -2154,6 +2200,22 @@ public:
bool willHaveBody() const { return WillHaveBody; }
void setWillHaveBody(bool V = true) { WillHaveBody = V; }
+ /// True if this function is considered a multiversioned function.
+ bool isMultiVersion() const { return getCanonicalDecl()->IsMultiVersion; }
+
+ /// Sets the multiversion state for this declaration and all of its
+ /// redeclarations.
+ void setIsMultiVersion(bool V = true) {
+ getCanonicalDecl()->IsMultiVersion = V;
+ }
+
+ /// True if this function is a multiversioned dispatch function as a part of
+ /// the cpu_specific/cpu_dispatch functionality.
+ bool isCPUDispatchMultiVersion() const;
+ /// True if this function is a multiversioned processor specific function as a
+ /// part of the cpu_specific/cpu_dispatch functionality.
+ bool isCPUSpecificMultiVersion() const;
+
void setPreviousDeclaration(FunctionDecl * PrevDecl);
FunctionDecl *getCanonicalDecl() override;
@@ -2209,34 +2271,34 @@ public:
return getType()->getAs<FunctionType>()->getReturnType();
}
- /// \brief Attempt to compute an informative source range covering the
+ /// 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 Attempt to compute an informative source range covering the
+ /// Attempt to compute an informative source range covering the
/// function exception specification, if any.
SourceRange getExceptionSpecSourceRange() const;
- /// \brief Determine the type of an expression that calls this function.
+ /// Determine the type of an expression that calls this function.
QualType getCallResultType() const {
assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!");
return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
}
- /// \brief Returns the WarnUnusedResultAttr that is either declared on this
+ /// Returns the WarnUnusedResultAttr that is either declared on this
/// function, or its return type declaration.
const Attr *getUnusedResultAttr() const;
- /// \brief Returns true if this function or its return type has the
+ /// Returns true if this function or its return type has the
/// warn_unused_result attribute.
bool hasUnusedResultAttr() const { return getUnusedResultAttr() != nullptr; }
- /// \brief Returns the storage class as written in the source. For the
+ /// Returns the storage class as written in the source. For the
/// computed linkage of symbol, see getLinkage.
StorageClass getStorageClass() const { return StorageClass(SClass); }
- /// \brief Determine whether the "inline" keyword was specified for this
+ /// Determine whether the "inline" keyword was specified for this
/// function.
bool isInlineSpecified() const { return IsInlineSpecified; }
@@ -2251,7 +2313,7 @@ public:
IsInline = true;
}
- /// \brief Determine whether this function should be inlined, because it is
+ /// Determine whether this function should be inlined, because it is
/// either marked "inline" or "constexpr" or is a member function of a class
/// that was defined in the class body.
bool isInlined() const { return IsInline; }
@@ -2262,8 +2324,8 @@ public:
bool doesDeclarationForceExternallyVisibleDefinition() const;
- /// isOverloadedOperator - Whether this function declaration
- /// represents an C++ overloaded operator, e.g., "operator+".
+ /// Whether this function declaration represents an C++ overloaded
+ /// operator, e.g., "operator+".
bool isOverloadedOperator() const {
return getOverloadedOperator() != OO_None;
}
@@ -2272,7 +2334,7 @@ public:
const IdentifierInfo *getLiteralIdentifier() const;
- /// \brief If this function is an instantiation of a member function
+ /// If this function is an instantiation of a member function
/// of a class template specialization, retrieves the function from
/// which it was instantiated.
///
@@ -2295,22 +2357,22 @@ public:
/// declaration returned by getInstantiatedFromMemberFunction().
FunctionDecl *getInstantiatedFromMemberFunction() const;
- /// \brief What kind of templated function this is.
+ /// What kind of templated function this is.
TemplatedKind getTemplatedKind() const;
- /// \brief If this function is an instantiation of a member function of a
+ /// If this function is an instantiation of a member function of a
/// class template specialization, retrieves the member specialization
/// information.
MemberSpecializationInfo *getMemberSpecializationInfo() const;
- /// \brief Specify that this record is an instantiation of the
+ /// Specify that this record is an instantiation of the
/// member function FD.
void setInstantiationOfMemberFunction(FunctionDecl *FD,
TemplateSpecializationKind TSK) {
setInstantiationOfMemberFunction(getASTContext(), FD, TSK);
}
- /// \brief Retrieves the function template that is described by this
+ /// Retrieves the function template that is described by this
/// function declaration.
///
/// Every function template is represented as a FunctionTemplateDecl
@@ -2326,50 +2388,50 @@ public:
void setDescribedFunctionTemplate(FunctionTemplateDecl *Template);
- /// \brief Determine whether this function is a function template
+ /// Determine whether this function is a function template
/// specialization.
bool isFunctionTemplateSpecialization() const {
return getPrimaryTemplate() != nullptr;
}
- /// \brief Retrieve the class scope template pattern that this function
+ /// Retrieve the class scope template pattern that this function
/// template specialization is instantiated from.
FunctionDecl *getClassScopeSpecializationPattern() const;
- /// \brief If this function is actually a function template specialization,
+ /// If this function is actually a function template specialization,
/// retrieve information about this function template specialization.
/// Otherwise, returns NULL.
FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const;
- /// \brief Determines whether this function is a function template
+ /// Determines whether this function is a function template
/// specialization or a member of a class template specialization that can
/// be implicitly instantiated.
bool isImplicitlyInstantiable() const;
- /// \brief Determines if the given function was instantiated from a
+ /// Determines if the given function was instantiated from a
/// function template.
bool isTemplateInstantiation() const;
- /// \brief Retrieve the function declaration from which this function could
+ /// Retrieve the function declaration from which this function could
/// be instantiated, if it is an instantiation (rather than a non-template
/// or a specialization, for example).
FunctionDecl *getTemplateInstantiationPattern() const;
- /// \brief Retrieve the primary template that this function template
+ /// Retrieve the primary template that this function template
/// specialization either specializes or was instantiated from.
///
/// If this function declaration is not a function template specialization,
/// returns NULL.
FunctionTemplateDecl *getPrimaryTemplate() const;
- /// \brief Retrieve the template arguments used to produce this function
+ /// Retrieve the template arguments used to produce this function
/// template specialization from the primary template.
///
/// If this function declaration is not a function template specialization,
/// returns NULL.
const TemplateArgumentList *getTemplateSpecializationArgs() const;
- /// \brief Retrieve the template argument list as written in the sources,
+ /// Retrieve the template argument list as written in the sources,
/// if any.
///
/// If this function declaration is not a function template specialization
@@ -2379,7 +2441,7 @@ public:
const ASTTemplateArgumentListInfo*
getTemplateSpecializationArgsAsWritten() const;
- /// \brief Specify that this function declaration is actually a function
+ /// Specify that this function declaration is actually a function
/// template specialization.
///
/// \param Template the function template that this function template
@@ -2409,7 +2471,7 @@ public:
PointOfInstantiation);
}
- /// \brief Specifies that this function declaration is actually a
+ /// Specifies that this function declaration is actually a
/// dependent function template specialization.
void setDependentTemplateSpecialization(ASTContext &Context,
const UnresolvedSetImpl &Templates,
@@ -2418,16 +2480,16 @@ public:
DependentFunctionTemplateSpecializationInfo *
getDependentSpecializationInfo() const;
- /// \brief Determine what kind of template instantiation this function
+ /// Determine what kind of template instantiation this function
/// represents.
TemplateSpecializationKind getTemplateSpecializationKind() const;
- /// \brief Determine what kind of template instantiation this function
+ /// Determine what kind of template instantiation this function
/// represents.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());
- /// \brief Retrieve the (first) point of instantiation of a function template
+ /// Retrieve the (first) point of instantiation of a function template
/// specialization or a member of a class template specialization.
///
/// \returns the first point of instantiation, if this function was
@@ -2435,20 +2497,24 @@ public:
/// location.
SourceLocation getPointOfInstantiation() const;
- /// \brief Determine whether this is or was instantiated from an out-of-line
+ /// Determine whether this is or was instantiated from an out-of-line
/// definition of a member function.
bool isOutOfLine() const override;
- /// \brief Identify a memory copying or setting function.
+ /// Identify a memory copying or setting function.
/// If the given function is a memory copy or setting function, returns
/// the corresponding Builtin ID. If the function is not a memory function,
/// returns 0.
unsigned getMemoryFunctionKind() const;
- /// \brief Returns ODRHash of the function. This value is calculated and
+ /// Returns ODRHash of the function. This value is calculated and
/// stored on first call, then the stored value returned on the other calls.
unsigned getODRHash();
+ /// Returns cached ODRHash of the function. This must have been previously
+ /// computed and stored.
+ unsigned getODRHash() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
@@ -2462,8 +2528,7 @@ public:
}
};
-/// FieldDecl - An instance of this class is created by Sema::ActOnField to
-/// represent a member of a struct/union/class.
+/// Represents a member of a struct/union/class.
class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
unsigned BitField : 1;
unsigned Mutable : 1;
@@ -2499,7 +2564,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
Expr *BitWidth;
};
- /// \brief Storage for either the bit-width, the in-class initializer, or
+ /// Storage for either the bit-width, the in-class initializer, or
/// both (via InitAndBitWidth), or the captured variable length array bound.
///
/// If the storage kind is ISK_InClassCopyInit or
@@ -2534,20 +2599,20 @@ public:
static FieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- /// getFieldIndex - Returns the index of this field within its record,
+ /// Returns the index of this field within its record,
/// as appropriate for passing to ASTRecordLayout::getFieldOffset.
unsigned getFieldIndex() const;
- /// isMutable - Determines whether this field is mutable (C++ only).
+ /// Determines whether this field is mutable (C++ only).
bool isMutable() const { return Mutable; }
- /// \brief Determines whether this field is a bitfield.
+ /// Determines whether this field is a bitfield.
bool isBitField() const { return BitField; }
- /// @brief Determines whether this is an unnamed bitfield.
+ /// Determines whether this is an unnamed bitfield.
bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); }
- /// isAnonymousStructOrUnion - Determines whether this field is a
+ /// Determines whether this field is a
/// representative for an anonymous struct or union. Such fields are
/// unnamed and are implicitly generated by the implementation to
/// store the data for the anonymous union or struct.
@@ -2564,7 +2629,7 @@ public:
unsigned getBitWidthValue(const ASTContext &Ctx) const;
- /// setBitWidth - Set the bit-field width for this member.
+ /// Set the bit-field width for this member.
// Note: used by some clients (i.e., do not remove it).
void setBitWidth(Expr *Width) {
assert(!hasCapturedVLAType() && !BitField &&
@@ -2578,7 +2643,7 @@ public:
BitField = true;
}
- /// removeBitWidth - Remove the bit-field width from this member.
+ /// Remove the bit-field width from this member.
// Note: used by some clients (i.e., do not remove it).
void removeBitWidth() {
assert(isBitField() && "no bitfield width to remove");
@@ -2586,6 +2651,11 @@ public:
BitField = false;
}
+ /// Is this a zero-length bit-field? Such bit-fields aren't really bit-fields
+ /// at all and instead act as a separator between contiguous runs of other
+ /// bit-fields.
+ bool isZeroLengthBitField(const ASTContext &Ctx) const;
+
/// Get the kind of (C++11) default member initializer that this field has.
InClassInitStyle getInClassInitStyle() const {
InitStorageKind storageKind = InitStorage.getInt();
@@ -2610,8 +2680,7 @@ public:
return static_cast<Expr*>(Ptr);
}
- /// setInClassInitializer - Set the C++11 in-class initializer for this
- /// member.
+ /// Set the C++11 in-class initializer for this member.
void setInClassInitializer(Expr *Init) {
assert(hasInClassInitializer() && !getInClassInitializer());
if (BitField)
@@ -2620,30 +2689,29 @@ public:
InitStorage.setPointer(Init);
}
- /// removeInClassInitializer - Remove the C++11 in-class initializer from this
- /// member.
+ /// Remove the C++11 in-class initializer from this member.
void removeInClassInitializer() {
assert(hasInClassInitializer() && "no initializer to remove");
InitStorage.setPointerAndInt(getBitWidth(), ISK_NoInit);
}
- /// \brief Determine whether this member captures the variable length array
+ /// Determine whether this member captures the variable length array
/// type.
bool hasCapturedVLAType() const {
return InitStorage.getInt() == ISK_CapturedVLAType;
}
- /// \brief Get the captured variable length array type.
+ /// Get the captured variable length array type.
const VariableArrayType *getCapturedVLAType() const {
return hasCapturedVLAType() ? static_cast<const VariableArrayType *>(
InitStorage.getPointer())
: nullptr;
}
- /// \brief Set the captured variable length array type for this field.
+ /// Set the captured variable length array type for this field.
void setCapturedVLAType(const VariableArrayType *VLAType);
- /// getParent - Returns the parent of this field declaration, which
+ /// Returns the parent of this field declaration, which
/// is the struct in which this field is defined.
const RecordDecl *getParent() const {
return cast<RecordDecl>(getDeclContext());
@@ -2664,7 +2732,7 @@ public:
static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
};
-/// EnumConstantDecl - An instance of this object exists for each enum constant
+/// An instance of this object exists for each enum constant
/// that is defined. For example, in "enum X {a,b}", each of a/b are
/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
/// TagType for the X EnumDecl.
@@ -2705,9 +2773,8 @@ public:
static bool classofKind(Kind K) { return K == EnumConstant; }
};
-/// IndirectFieldDecl - An instance of this class is created to represent a
-/// field injected from an anonymous union/struct into the parent scope.
-/// IndirectFieldDecl are always implicit.
+/// Represents a field injected from an anonymous union/struct into the parent
+/// scope. These are always implicit.
class IndirectFieldDecl : public ValueDecl,
public Mergeable<IndirectFieldDecl> {
NamedDecl **Chaining;
@@ -2756,17 +2823,17 @@ public:
static bool classofKind(Kind K) { return K == IndirectField; }
};
-/// TypeDecl - Represents a declaration of a type.
+/// Represents a declaration of a type.
class TypeDecl : public NamedDecl {
friend class ASTContext;
- /// TypeForDecl - This indicates the Type object that represents
+ /// This indicates the Type object that represents
/// this TypeDecl. It is a cache maintained by
/// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
/// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl.
mutable const Type *TypeForDecl = nullptr;
- /// LocStart - The start of the source range for this declaration.
+ /// The start of the source range for this declaration.
SourceLocation LocStart;
void anchor() override;
@@ -2800,13 +2867,16 @@ public:
/// Base class for declarations which introduce a typedef-name.
class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
- using ModedTInfo = std::pair<TypeSourceInfo *, QualType>;
- llvm::PointerUnion<TypeSourceInfo *, ModedTInfo *> MaybeModedTInfo;
+ struct alignas(8) ModedTInfo {
+ TypeSourceInfo *first;
+ QualType second;
+ };
- // FIXME: This can be packed into the bitfields in Decl.
- /// If 0, we have not computed IsTransparentTag.
- /// Otherwise, IsTransparentTag is (CacheIsTransparentTag >> 1).
- mutable unsigned CacheIsTransparentTag : 2;
+ /// If int part is 0, we have not computed IsTransparentTag.
+ /// Otherwise, IsTransparentTag is (getInt() >> 1).
+ mutable llvm::PointerIntPair<
+ llvm::PointerUnion<TypeSourceInfo *, ModedTInfo *>, 2>
+ MaybeModedTInfo;
void anchor() override;
@@ -2815,7 +2885,7 @@ protected:
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo)
: TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
- MaybeModedTInfo(TInfo), CacheIsTransparentTag(0) {}
+ MaybeModedTInfo(TInfo, 0) {}
using redeclarable_base = Redeclarable<TypedefNameDecl>;
@@ -2842,26 +2912,29 @@ public:
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
- bool isModed() const { return MaybeModedTInfo.is<ModedTInfo*>(); }
+ bool isModed() const {
+ return MaybeModedTInfo.getPointer().is<ModedTInfo *>();
+ }
TypeSourceInfo *getTypeSourceInfo() const {
- return isModed()
- ? MaybeModedTInfo.get<ModedTInfo*>()->first
- : MaybeModedTInfo.get<TypeSourceInfo*>();
+ return isModed() ? MaybeModedTInfo.getPointer().get<ModedTInfo *>()->first
+ : MaybeModedTInfo.getPointer().get<TypeSourceInfo *>();
}
QualType getUnderlyingType() const {
- return isModed()
- ? MaybeModedTInfo.get<ModedTInfo*>()->second
- : MaybeModedTInfo.get<TypeSourceInfo*>()->getType();
+ return isModed() ? MaybeModedTInfo.getPointer().get<ModedTInfo *>()->second
+ : MaybeModedTInfo.getPointer()
+ .get<TypeSourceInfo *>()
+ ->getType();
}
void setTypeSourceInfo(TypeSourceInfo *newType) {
- MaybeModedTInfo = newType;
+ MaybeModedTInfo.setPointer(newType);
}
void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) {
- MaybeModedTInfo = new (getASTContext()) ModedTInfo(unmodedTSI, modedTy);
+ MaybeModedTInfo.setPointer(new (getASTContext(), 8)
+ ModedTInfo({unmodedTSI, modedTy}));
}
/// Retrieves the canonical declaration of this typedef-name.
@@ -2878,8 +2951,8 @@ public:
/// Determines if this typedef shares a name and spelling location with its
/// underlying tag type, as is the case with the NS_ENUM macro.
bool isTransparentTag() const {
- if (CacheIsTransparentTag)
- return CacheIsTransparentTag & 0x2;
+ if (MaybeModedTInfo.getInt())
+ return MaybeModedTInfo.getInt() & 0x2;
return isTransparentTagSlow();
}
@@ -2893,7 +2966,7 @@ private:
bool isTransparentTagSlow() const;
};
-/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
+/// Represents the declaration of a typedef-name via the 'typedef'
/// type specifier.
class TypedefDecl : public TypedefNameDecl {
TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
@@ -2913,7 +2986,7 @@ public:
static bool classofKind(Kind K) { return K == Typedef; }
};
-/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
+/// Represents the declaration of a typedef-name via a C++11
/// alias-declaration.
class TypeAliasDecl : public TypedefNameDecl {
/// The template for which this is the pattern, if any.
@@ -2940,7 +3013,7 @@ public:
static bool classofKind(Kind K) { return K == TypeAlias; }
};
-/// TagDecl - Represents the declaration of a struct/union/class/enum.
+/// Represents the declaration of a struct/union/class/enum.
class TagDecl
: public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
public:
@@ -2949,25 +3022,24 @@ public:
private:
// FIXME: This can be packed into the bitfields in Decl.
- /// TagDeclKind - The TagKind enum.
+ /// The TagKind enum.
unsigned TagDeclKind : 3;
- /// IsCompleteDefinition - True if this is a definition ("struct foo
- /// {};"), false if it is a declaration ("struct foo;"). It is not
- /// a definition until the definition has been fully processed.
+ /// True if this is a definition ("struct foo {};"), false if it is a
+ /// declaration ("struct foo;"). It is not considered a definition
+ /// until the definition has been fully processed.
unsigned IsCompleteDefinition : 1;
protected:
- /// IsBeingDefined - True if this is currently being defined.
+ /// True if this is currently being defined.
unsigned IsBeingDefined : 1;
private:
- /// IsEmbeddedInDeclarator - True if this tag declaration is
- /// "embedded" (i.e., defined or declared for the very first time)
- /// in the syntax of a declarator.
+ /// True if this tag declaration is "embedded" (i.e., defined or declared
+ /// for the very first time) in the syntax of a declarator.
unsigned IsEmbeddedInDeclarator : 1;
- /// \brief True if this tag is free standing, e.g. "struct foo;".
+ /// True if this tag is free standing, e.g. "struct foo;".
unsigned IsFreeStanding : 1;
protected:
@@ -2975,21 +3047,21 @@ protected:
unsigned NumPositiveBits : 8;
unsigned NumNegativeBits : 8;
- /// IsScoped - True if this tag declaration is a scoped enumeration. Only
+ /// True if this tag declaration is a scoped enumeration. Only
/// possible in C++11 mode.
unsigned IsScoped : 1;
- /// IsScopedUsingClassTag - If this tag declaration is a scoped enum,
+ /// If this tag declaration is a scoped enum,
/// then this is true if the scoped enum was declared using the class
/// tag, false if it was declared with the struct tag. No meaning is
/// associated if this tag declaration is not a scoped enum.
unsigned IsScopedUsingClassTag : 1;
- /// IsFixed - True if this is an enumeration with fixed underlying type. Only
+ /// True if this is an enumeration with fixed underlying type. Only
/// possible in C++11, Microsoft extensions, or Objective C mode.
unsigned IsFixed : 1;
- /// \brief Indicates whether it is possible for declarations of this kind
+ /// Indicates whether it is possible for declarations of this kind
/// to have an out-of-date definition.
///
/// This option is only enabled when modules are enabled.
@@ -3006,7 +3078,7 @@ private:
// to be used for the (uncommon) case of out-of-line declarations.
using ExtInfo = QualifierInfo;
- /// \brief If the (out-of-line) tag declaration name
+ /// If the (out-of-line) tag declaration name
/// is qualified, it points to the qualifier info (nns and range);
/// otherwise, if the tag declaration is anonymous and it is part of
/// a typedef or alias, it points to the TypedefNameDecl (used for mangling);
@@ -3050,7 +3122,7 @@ protected:
return getMostRecentDecl();
}
- /// @brief Completes the definition of this tag declaration.
+ /// Completes the definition of this tag declaration.
///
/// This is a helper function for derived classes.
void completeDefinition();
@@ -3072,11 +3144,11 @@ public:
SourceRange getBraceRange() const { return BraceRange; }
void setBraceRange(SourceRange R) { BraceRange = R; }
- /// getInnerLocStart - Return SourceLocation representing start of source
+ /// Return SourceLocation representing start of source
/// range ignoring outer template declarations.
SourceLocation getInnerLocStart() const { return getLocStart(); }
- /// getOuterLocStart - Return SourceLocation representing start of source
+ /// Return SourceLocation representing start of source
/// range taking into account any outer template declarations.
SourceLocation getOuterLocStart() const;
SourceRange getSourceRange() const override LLVM_READONLY;
@@ -3086,25 +3158,24 @@ public:
return const_cast<TagDecl*>(this)->getCanonicalDecl();
}
- /// isThisDeclarationADefinition() - Return true if this declaration
- /// is a completion definition of the type. Provided for consistency.
+ /// Return true if this declaration is a completion definition of the type.
+ /// Provided for consistency.
bool isThisDeclarationADefinition() const {
return isCompleteDefinition();
}
- /// isCompleteDefinition - Return true if this decl has its body
- /// fully specified.
+ /// Return true if this decl has its body fully specified.
bool isCompleteDefinition() const {
return IsCompleteDefinition;
}
- /// \brief Return true if this complete decl is
+ /// Return true if this complete decl is
/// required to be complete for some existing use.
bool isCompleteDefinitionRequired() const {
return IsCompleteDefinitionRequired;
}
- /// isBeingDefined - Return true if this decl is currently being defined.
+ /// Return true if this decl is currently being defined.
bool isBeingDefined() const {
return IsBeingDefined;
}
@@ -3121,19 +3192,19 @@ public:
IsFreeStanding = isFreeStanding;
}
- /// \brief Whether this declaration declares a type that is
+ /// Whether this declaration declares a type that is
/// dependent, i.e., a type that somehow depends on template
/// parameters.
bool isDependentType() const { return isDependentContext(); }
- /// @brief Starts the definition of this tag declaration.
+ /// Starts the definition of this tag declaration.
///
/// This method should be invoked at the beginning of the definition
/// of this tag declaration. It will set the tag type into a state
/// where it is in the process of being defined.
void startDefinition();
- /// getDefinition - Returns the TagDecl that actually defines this
+ /// Returns the TagDecl that actually defines this
/// struct/union/class/enum. When determining whether or not a
/// struct/union/class/enum has a definition, one should use this
/// method as opposed to 'isDefinition'. 'isDefinition' indicates
@@ -3191,14 +3262,14 @@ public:
void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
- /// \brief Retrieve the nested-name-specifier that qualifies the name of this
+ /// Retrieve the nested-name-specifier that qualifies the name of this
/// declaration, if it was present in the source.
NestedNameSpecifier *getQualifier() const {
return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
: nullptr;
}
- /// \brief Retrieve the nested-name-specifier (with source-location
+ /// Retrieve the nested-name-specifier (with source-location
/// information) that qualifies the name of this declaration, if it was
/// present in the source.
NestedNameSpecifierLoc getQualifierLoc() const {
@@ -3233,11 +3304,11 @@ public:
}
};
-/// EnumDecl - Represents an enum. In C++11, enums can be forward-declared
+/// Represents an enum. In C++11, enums can be forward-declared
/// 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 {
- /// IntegerType - This represent the integer type that the enum corresponds
+ /// 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.
///
@@ -3253,17 +3324,21 @@ class EnumDecl : public TagDecl {
/// extra pointer when TypeSourceInfo is needed.
llvm::PointerUnion<const Type *, TypeSourceInfo *> IntegerType;
- /// PromotionType - The integer type that values of this type should
+ /// The integer type that values of this type should
/// promote to. In C, enumerators are generally of an integer type
/// directly, but gcc-style large enumerators (and all enumerators
/// in C++) are of the enum type instead.
QualType PromotionType;
- /// \brief If this enumeration is an instantiation of a member enumeration
+ /// If this enumeration is an instantiation of a member enumeration
/// of a class template specialization, this is the member specialization
/// information.
MemberSpecializationInfo *SpecializationInfo = nullptr;
+ /// Store the ODRHash after first calculation.
+ unsigned HasODRHash : 1;
+ unsigned ODRHash;
+
EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl,
bool Scoped, bool ScopedUsingClassTag, bool Fixed)
@@ -3275,6 +3350,8 @@ class EnumDecl : public TagDecl {
IsScoped = Scoped;
IsScopedUsingClassTag = ScopedUsingClassTag;
IsFixed = Fixed;
+ HasODRHash = false;
+ ODRHash = 0;
}
void anchor() override;
@@ -3317,9 +3394,9 @@ public:
bool IsFixed);
static EnumDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- /// completeDefinition - When created, the EnumDecl corresponds to a
+ /// When created, the EnumDecl corresponds to a
/// forward-declared enum. This method is used to mark the
- /// declaration as being defined; it's enumerators have already been
+ /// declaration as being defined; its enumerators have already been
/// added (via DeclContext::addDecl). NewType is the new underlying
/// type of the enumeration type.
void completeDefinition(QualType NewType,
@@ -3327,8 +3404,7 @@ public:
unsigned NumPositiveBits,
unsigned NumNegativeBits);
- // enumerator_iterator - Iterates through the enumerators of this
- // enumeration.
+ // Iterates through the enumerators of this enumeration.
using enumerator_iterator = specific_decl_iterator<EnumConstantDecl>;
using enumerator_range =
llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>;
@@ -3351,14 +3427,13 @@ public:
return enumerator_iterator(E->decls_end());
}
- /// getPromotionType - Return the integer type that enumerators
- /// should promote to.
+ /// Return the integer type that enumerators should promote to.
QualType getPromotionType() const { return PromotionType; }
- /// \brief Set the promotion type.
+ /// Set the promotion type.
void setPromotionType(QualType T) { PromotionType = T; }
- /// getIntegerType - Return the integer type this enum decl corresponds to.
+ /// Return the integer type this enum decl corresponds to.
/// This returns a null QualType for an enum forward definition with no fixed
/// underlying type.
QualType getIntegerType() const {
@@ -3369,23 +3444,23 @@ public:
return IntegerType.get<TypeSourceInfo*>()->getType().getUnqualifiedType();
}
- /// \brief Set the underlying integer type.
+ /// Set the underlying integer type.
void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); }
- /// \brief Set the underlying integer type source info.
+ /// Set the underlying integer type source info.
void setIntegerTypeSourceInfo(TypeSourceInfo *TInfo) { IntegerType = TInfo; }
- /// \brief Return the type source info for the underlying integer type,
+ /// Return the type source info for the underlying integer type,
/// if no type source info exists, return 0.
TypeSourceInfo *getIntegerTypeSourceInfo() const {
return IntegerType.dyn_cast<TypeSourceInfo*>();
}
- /// \brief Retrieve the source range that covers the underlying type if
+ /// 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
+ /// Returns the width in bits required to store all the
/// non-negative enumerators of this enum.
unsigned getNumPositiveBits() const {
return NumPositiveBits;
@@ -3395,7 +3470,7 @@ public:
assert(NumPositiveBits == Num && "can't store this bitcount");
}
- /// \brief Returns the width in bits required to store all the
+ /// Returns the width in bits required to store all the
/// negative enumerators of this enum. These widths include
/// the rightmost leading 1; that is:
///
@@ -3411,25 +3486,29 @@ public:
NumNegativeBits = Num;
}
- /// \brief Returns true if this is a C++11 scoped enumeration.
+ /// Returns true if this is a C++11 scoped enumeration.
bool isScoped() const {
return IsScoped;
}
- /// \brief Returns true if this is a C++11 scoped enumeration.
+ /// Returns true if this is a C++11 scoped enumeration.
bool isScopedUsingClassTag() const {
return IsScopedUsingClassTag;
}
- /// \brief Returns true if this is an Objective-C, C++11, or
+ /// Returns true if this is an Objective-C, C++11, or
/// Microsoft-style enumeration with a fixed underlying type.
bool isFixed() const {
return IsFixed;
}
- /// \brief Returns true if this can be considered a complete type.
+ unsigned getODRHash();
+
+ /// Returns true if this can be considered a complete type.
bool isComplete() const {
- return isCompleteDefinition() || isFixed();
+ // IntegerType is set for fixed type enums and non-fixed but implicitly
+ // int-sized Microsoft enums.
+ return isCompleteDefinition() || IntegerType;
}
/// Returns true if this enum is either annotated with
@@ -3444,33 +3523,33 @@ public:
/// enum_extensibility(open).
bool isClosedNonFlag() const;
- /// \brief Retrieve the enum definition from which this enumeration could
+ /// Retrieve the enum definition from which this enumeration could
/// be instantiated, if it is an instantiation (rather than a non-template).
EnumDecl *getTemplateInstantiationPattern() const;
- /// \brief Returns the enumeration (declared within the template)
+ /// Returns the enumeration (declared within the template)
/// from which this enumeration type was instantiated, or NULL if
/// this enumeration was not instantiated from any template.
EnumDecl *getInstantiatedFromMemberEnum() const;
- /// \brief If this enumeration is a member of a specialization of a
+ /// If this enumeration is a member of a specialization of a
/// templated class, determine what kind of template specialization
/// or instantiation this is.
TemplateSpecializationKind getTemplateSpecializationKind() const;
- /// \brief For an enumeration member that was instantiated from a member
+ /// For an enumeration member that was instantiated from a member
/// enumeration of a templated class, set the template specialiation kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());
- /// \brief If this enumeration is an instantiation of a member enumeration of
+ /// If this enumeration is an instantiation of a member enumeration of
/// a class template specialization, retrieves the member specialization
/// information.
MemberSpecializationInfo *getMemberSpecializationInfo() const {
return SpecializationInfo;
}
- /// \brief Specify that this enumeration is an instantiation of the
+ /// Specify that this enumeration is an instantiation of the
/// member enumeration ED.
void setInstantiationOfMemberEnum(EnumDecl *ED,
TemplateSpecializationKind TSK) {
@@ -3481,36 +3560,74 @@ public:
static bool classofKind(Kind K) { return K == Enum; }
};
-/// RecordDecl - Represents a struct/union/class. For example:
+/// Represents a struct/union/class. For example:
/// struct X; // Forward declaration, no "body".
/// union Y { int A, B; }; // Has body with members A and B (FieldDecls).
/// This decl will be marked invalid if *any* members are invalid.
class RecordDecl : public TagDecl {
+public:
+ /// Enum that represents the different ways arguments are passed to and
+ /// returned from function calls. This takes into account the target-specific
+ /// and version-specific rules along with the rules determined by the
+ /// language.
+ enum ArgPassingKind : unsigned {
+ /// The argument of this type can be passed directly in registers.
+ APK_CanPassInRegs,
+
+ /// The argument of this type cannot be passed directly in registers.
+ /// Records containing this type as a subobject are not forced to be passed
+ /// indirectly. This value is used only in C++. This value is required by
+ /// C++ because, in uncommon situations, it is possible for a class to have
+ /// only trivial copy/move constructors even when one of its subobjects has
+ /// a non-trivial copy/move constructor (if e.g. the corresponding copy/move
+ /// constructor in the derived class is deleted).
+ APK_CannotPassInRegs,
+
+ /// The argument of this type cannot be passed directly in registers.
+ /// Records containing this type as a subobject are forced to be passed
+ /// indirectly.
+ APK_CanNeverPassInRegs
+ };
+
+private:
friend class DeclContext;
// FIXME: This can be packed into the bitfields in Decl.
- /// HasFlexibleArrayMember - This is true if this struct ends with a flexible
+ /// This is true if this struct ends with a flexible
/// array member (e.g. int X[]) or if this union contains a struct that does.
/// If so, this cannot be contained in arrays or other structs as a member.
- bool HasFlexibleArrayMember : 1;
+ unsigned HasFlexibleArrayMember : 1;
- /// AnonymousStructOrUnion - Whether this is the type of an anonymous struct
- /// or union.
- bool AnonymousStructOrUnion : 1;
+ /// Whether this is the type of an anonymous struct or union.
+ unsigned AnonymousStructOrUnion : 1;
- /// HasObjectMember - This is true if this struct has at least one member
+ /// This is true if this struct has at least one member
/// containing an Objective-C object pointer type.
- bool HasObjectMember : 1;
-
- /// HasVolatileMember - This is true if struct has at least one member of
+ unsigned HasObjectMember : 1;
+
+ /// This is true if struct has at least one member of
/// 'volatile' type.
- bool HasVolatileMember : 1;
+ unsigned HasVolatileMember : 1;
- /// \brief Whether the field declarations of this record have been loaded
+ /// Whether the field declarations of this record have been loaded
/// from external storage. To avoid unnecessary deserialization of
/// methods/nested types we allow deserialization of just the fields
/// when needed.
- mutable bool LoadedFieldsFromExternalStorage : 1;
+ mutable unsigned LoadedFieldsFromExternalStorage : 1;
+
+ /// Basic properties of non-trivial C structs.
+ unsigned NonTrivialToPrimitiveDefaultInitialize : 1;
+ unsigned NonTrivialToPrimitiveCopy : 1;
+ unsigned NonTrivialToPrimitiveDestroy : 1;
+
+ /// Indicates whether this struct is destroyed in the callee.
+ ///
+ /// Please note that MSVC won't merge adjacent bitfields if they don't have
+ /// the same type.
+ unsigned ParamDestroyedInCallee : 1;
+
+ /// Represents the way this type is passed to a function.
+ unsigned ArgPassingRestrictions : 2;
protected:
RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
@@ -3541,10 +3658,9 @@ public:
bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
- /// isAnonymousStructOrUnion - Whether this is an anonymous struct
- /// or union. To be an anonymous struct or union, it must have been
- /// declared without a name and there must be no objects of this
- /// type declared, e.g.,
+ /// Whether this is an anonymous struct or union. To be an anonymous
+ /// struct or union, it must have been declared without a name and
+ /// there must be no objects of this type declared, e.g.,
/// @code
/// union { int i; float f; };
/// @endcode
@@ -3571,7 +3687,55 @@ public:
LoadedFieldsFromExternalStorage = val;
}
- /// \brief Determines whether this declaration represents the
+ /// Functions to query basic properties of non-trivial C structs.
+ bool isNonTrivialToPrimitiveDefaultInitialize() const {
+ return NonTrivialToPrimitiveDefaultInitialize;
+ }
+
+ void setNonTrivialToPrimitiveDefaultInitialize(bool V) {
+ NonTrivialToPrimitiveDefaultInitialize = V;
+ }
+
+ bool isNonTrivialToPrimitiveCopy() const {
+ return NonTrivialToPrimitiveCopy;
+ }
+
+ void setNonTrivialToPrimitiveCopy(bool V) {
+ NonTrivialToPrimitiveCopy = V;
+ }
+
+ bool isNonTrivialToPrimitiveDestroy() const {
+ return NonTrivialToPrimitiveDestroy;
+ }
+
+ void setNonTrivialToPrimitiveDestroy(bool V) {
+ NonTrivialToPrimitiveDestroy = V;
+ }
+
+ /// Determine whether this class can be passed in registers. In C++ mode,
+ /// it must have at least one trivial, non-deleted copy or move constructor.
+ /// FIXME: This should be set as part of completeDefinition.
+ bool canPassInRegisters() const {
+ return getArgPassingRestrictions() == APK_CanPassInRegs;
+ }
+
+ ArgPassingKind getArgPassingRestrictions() const {
+ return static_cast<ArgPassingKind>(ArgPassingRestrictions);
+ }
+
+ void setArgPassingRestrictions(ArgPassingKind Kind) {
+ ArgPassingRestrictions = static_cast<uint8_t>(Kind);
+ }
+
+ bool isParamDestroyedInCallee() const {
+ return ParamDestroyedInCallee;
+ }
+
+ void setParamDestroyedInCallee(bool V) {
+ ParamDestroyedInCallee = V;
+ }
+
+ /// Determines whether this declaration represents the
/// injected class name.
///
/// The injected class name in C++ is the name of the class that
@@ -3586,19 +3750,19 @@ public:
/// \endcode
bool isInjectedClassName() const;
- /// \brief Determine whether this record is a class describing a lambda
+ /// Determine whether this record is a class describing a lambda
/// function object.
bool isLambda() const;
- /// \brief Determine whether this record is a record for captured variables in
+ /// Determine whether this record is a record for captured variables in
/// CapturedStmt construct.
bool isCapturedRecord() const;
- /// \brief Mark the record as a record for captured variables in CapturedStmt
+ /// Mark the record as a record for captured variables in CapturedStmt
/// construct.
void setCapturedRecord();
- /// getDefinition - Returns the RecordDecl that actually defines
+ /// Returns the RecordDecl that actually defines
/// this struct/union/class. When determining whether or not a
/// struct/union/class is completely defined, one should use this
/// method as opposed to 'isCompleteDefinition'.
@@ -3623,14 +3787,12 @@ public:
return field_iterator(decl_iterator());
}
- // field_empty - Whether there are any fields (non-static data
- // members) in this record.
+ // Whether there are any fields (non-static data members) in this record.
bool field_empty() const {
return field_begin() == field_end();
}
- /// completeDefinition - Notes that the definition of this type is
- /// now complete.
+ /// Note that the definition of this type is now complete.
virtual void completeDefinition();
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -3638,12 +3800,12 @@ public:
return K >= firstRecord && K <= lastRecord;
}
- /// \brief Get whether or not this is an ms_struct which can
+ /// Get whether or not this is an ms_struct which can
/// be turned on with an attribute, pragma, or -mms-bitfields
/// commandline option.
bool isMsStruct(const ASTContext &C) const;
- /// \brief Whether we are allowed to insert extra padding between fields.
+ /// Whether we are allowed to insert extra padding between fields.
/// These padding are added to help AddressSanitizer detect
/// intra-object-overflow bugs.
bool mayInsertExtraPadding(bool EmitRemark = false) const;
@@ -3653,7 +3815,7 @@ public:
const FieldDecl *findFirstNamedDataMember() const;
private:
- /// \brief Deserialize just the fields.
+ /// Deserialize just the fields.
void LoadFieldsFromExternalStorage() const;
};
@@ -3689,7 +3851,7 @@ public:
static bool classofKind(Kind K) { return K == FileScopeAsm; }
};
-/// BlockDecl - This represents a block literal declaration, which is like an
+/// Pepresents a block literal declaration, which is like an
/// unnamed FunctionDecl. For example:
/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body }
class BlockDecl : public Decl, public DeclContext {
@@ -3739,7 +3901,11 @@ private:
bool BlockMissingReturnType : 1;
bool IsConversionFromLambda : 1;
- /// ParamInfo - new[]'d array of pointers to ParmVarDecls for the formal
+ /// A bit that indicates this block is passed directly to a function as a
+ /// non-escaping parameter.
+ bool DoesNotEscape : 1;
+
+ /// A new[]'d array of pointers to ParmVarDecls for the formal
/// parameters of this function. This is null if a prototype or if there are
/// no formals.
ParmVarDecl **ParamInfo = nullptr;
@@ -3758,7 +3924,7 @@ protected:
BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
: Decl(Block, DC, CaretLoc), DeclContext(Block), IsVariadic(false),
CapturesCXXThis(false), BlockMissingReturnType(true),
- IsConversionFromLambda(false) {}
+ IsConversionFromLambda(false), DoesNotEscape(false) {}
public:
static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
@@ -3808,11 +3974,11 @@ public:
void setParams(ArrayRef<ParmVarDecl *> NewParamInfo);
- /// hasCaptures - True if this block (or its nested blocks) captures
+ /// True if this block (or its nested blocks) captures
/// anything of local storage from its enclosing scopes.
bool hasCaptures() const { return NumCaptures != 0 || CapturesCXXThis; }
- /// getNumCaptures - Returns the number of captured variables.
+ /// Returns the number of captured variables.
/// Does not include an entry for 'this'.
unsigned getNumCaptures() const { return NumCaptures; }
@@ -3830,6 +3996,9 @@ public:
bool isConversionFromLambda() const { return IsConversionFromLambda; }
void setIsConversionFromLambda(bool val) { IsConversionFromLambda = val; }
+ bool doesNotEscape() const { return DoesNotEscape; }
+ void setDoesNotEscape() { DoesNotEscape = true; }
+
bool capturesVariable(const VarDecl *var) const;
void setCaptures(ASTContext &Context, ArrayRef<Capture> Captures,
@@ -3861,8 +4030,7 @@ public:
}
};
-/// \brief This represents the body of a CapturedStmt, and serves as its
-/// DeclContext.
+/// Represents the body of a CapturedStmt, and serves as its DeclContext.
class CapturedDecl final
: public Decl,
public DeclContext,
@@ -3873,13 +4041,13 @@ protected:
}
private:
- /// \brief The number of parameters to the outlined function.
+ /// The number of parameters to the outlined function.
unsigned NumParams;
- /// \brief The position of context parameter in list of parameters.
+ /// The position of context parameter in list of parameters.
unsigned ContextParam;
- /// \brief The body of the outlined function.
+ /// The body of the outlined function.
llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
explicit CapturedDecl(DeclContext *DC, unsigned NumParams);
@@ -3927,7 +4095,7 @@ public:
return {getParams(), getNumParams()};
}
- /// \brief Retrieve the parameter containing captured variables.
+ /// Retrieve the parameter containing captured variables.
ImplicitParamDecl *getContextParam() const {
assert(ContextParam < NumParams);
return getParam(ContextParam);
@@ -3942,9 +4110,9 @@ public:
using param_iterator = ImplicitParamDecl *const *;
using param_range = llvm::iterator_range<param_iterator>;
- /// \brief Retrieve an iterator pointing to the first parameter decl.
+ /// 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.
+ /// Retrieve an iterator one past the last parameter decl.
param_iterator param_end() const { return getParams() + NumParams; }
// Implement isa/cast/dyncast/etc.
@@ -3958,7 +4126,7 @@ public:
}
};
-/// \brief Describes a module import declaration, which makes the contents
+/// Describes a module import declaration, which makes the contents
/// of the named module visible in the current translation unit.
///
/// An import declaration imports the named module (or submodule). For example:
@@ -3975,7 +4143,7 @@ class ImportDecl final : public Decl,
friend class ASTReader;
friend TrailingObjects;
- /// \brief The imported module, along with a bit that indicates whether
+ /// The imported module, along with a bit that indicates whether
/// we have source-location information for each identifier in the module
/// name.
///
@@ -3983,7 +4151,7 @@ class ImportDecl final : public Decl,
/// end of the import declaration.
llvm::PointerIntPair<Module *, 1, bool> ImportedAndComplete;
- /// \brief The next import in the list of imports local to the translation
+ /// The next import in the list of imports local to the translation
/// unit being parsed (not loaded from an AST file).
ImportDecl *NextLocalImport = nullptr;
@@ -3996,25 +4164,25 @@ class ImportDecl final : public Decl,
ImportDecl(EmptyShell Empty) : Decl(Import, Empty) {}
public:
- /// \brief Create a new module import declaration.
+ /// Create a new module import declaration.
static ImportDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, Module *Imported,
ArrayRef<SourceLocation> IdentifierLocs);
- /// \brief Create a new module import declaration for an implicitly-generated
+ /// Create a new module import declaration for an implicitly-generated
/// import.
static ImportDecl *CreateImplicit(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, Module *Imported,
SourceLocation EndLoc);
- /// \brief Create a new, deserialized module import declaration.
+ /// Create a new, deserialized module import declaration.
static ImportDecl *CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumLocations);
- /// \brief Retrieve the module that was imported by the import declaration.
+ /// Retrieve the module that was imported by the import declaration.
Module *getImportedModule() const { return ImportedAndComplete.getPointer(); }
- /// \brief Retrieves the locations of each of the identifiers that make up
+ /// Retrieves the locations of each of the identifiers that make up
/// the complete module name in the import declaration.
///
/// This will return an empty array if the locations of the individual
@@ -4027,7 +4195,7 @@ public:
static bool classofKind(Kind K) { return K == Import; }
};
-/// \brief Represents a C++ Modules TS module export declaration.
+/// Represents a C++ Modules TS module export declaration.
///
/// For example:
/// \code
@@ -4039,7 +4207,7 @@ class ExportDecl final : public Decl, public DeclContext {
private:
friend class ASTDeclReader;
- /// \brief The source location for the right brace (if valid).
+ /// The source location for the right brace (if valid).
SourceLocation RBraceLoc;
ExportDecl(DeclContext *DC, SourceLocation ExportLoc)
@@ -4077,7 +4245,7 @@ public:
}
};
-/// \brief Represents an empty-declaration.
+/// Represents an empty-declaration.
class EmptyDecl : public Decl {
EmptyDecl(DeclContext *DC, SourceLocation L) : Decl(Empty, DC, L) {}
@@ -4111,7 +4279,7 @@ 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() &&
+ assert(RedeclLink.isFirst() &&
"setPreviousDecl on a decl already in a redeclaration chain");
if (PrevDecl) {
@@ -4119,7 +4287,7 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
// redeclaration, or we can build invalid chains. If the most recent
// redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
First = PrevDecl->getFirstDecl();
- assert(First->RedeclLink.NextIsLatest() && "Expected first");
+ assert(First->RedeclLink.isFirst() && "Expected first");
decl_type *MostRecent = First->getNextRedeclaration();
RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent));
@@ -4142,7 +4310,7 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
// Inline function definitions.
-/// \brief Check if the given decl is complete.
+/// Check if the given decl is complete.
///
/// We use this function to break a cycle between the inline definitions in
/// Type.h and Decl.h.
@@ -4150,7 +4318,7 @@ inline bool IsEnumDeclComplete(EnumDecl *ED) {
return ED->isComplete();
}
-/// \brief Check if the given decl is scoped.
+/// Check if the given decl is scoped.
///
/// We use this function to break a cycle between the inline definitions in
/// Type.h and Decl.h.
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index f93c9f0b9aaa1..f99bd627877c5 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -19,7 +19,6 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
@@ -28,6 +27,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/VersionTuple.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -67,7 +67,7 @@ class TemplateDecl;
class TranslationUnitDecl;
class UsingDirectiveDecl;
-/// \brief Captures the result of checking the availability of a
+/// Captures the result of checking the availability of a
/// declaration.
enum AvailabilityResult {
AR_Available = 0,
@@ -83,9 +83,9 @@ enum AvailabilityResult {
/// (and its subclasses) in its Decl::operator new(). Proper alignment
/// of all subclasses (not requiring more than the alignment of Decl) is
/// asserted in DeclBase.cpp.
-class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
+class alignas(8) Decl {
public:
- /// \brief Lists the kind of concrete classes of Decl.
+ /// Lists the kind of concrete classes of Decl.
enum Kind {
#define DECL(DERIVED, BASE) DERIVED,
#define ABSTRACT_DECL(DECL)
@@ -96,7 +96,7 @@ public:
#include "clang/AST/DeclNodes.inc"
};
- /// \brief A placeholder type used to construct an empty shell of a
+ /// A placeholder type used to construct an empty shell of a
/// decl-derived type that will be filled in later (e.g., by some
/// deserialization method).
struct EmptyShell {};
@@ -231,7 +231,7 @@ public:
};
protected:
- /// \brief The next declaration within the same lexical
+ /// The next declaration within the same lexical
/// DeclContext. These pointers form the linked list that is
/// traversed via DeclContext's decls_begin()/decls_end().
///
@@ -288,27 +288,28 @@ private:
/// the implementation rather than explicitly written by the user.
unsigned Implicit : 1;
- /// \brief Whether this declaration was "used", meaning that a definition is
+ /// Whether this declaration was "used", meaning that a definition is
/// required.
unsigned Used : 1;
- /// \brief Whether this declaration was "referenced".
+ /// Whether this declaration was "referenced".
/// The difference with 'Used' is whether the reference appears in a
/// evaluated context or not, e.g. functions used in uninstantiated templates
/// are regarded as "referenced" but not "used".
unsigned Referenced : 1;
- /// \brief Whether this declaration is a top-level declaration (function,
+ /// Whether this declaration is a top-level declaration (function,
/// global variable, etc.) that is lexically inside an objc container
/// definition.
unsigned TopLevelDeclInObjCContainer : 1;
- /// \brief Whether statistic collection is enabled.
+ /// Whether statistic collection is enabled.
static bool StatisticsEnabled;
protected:
friend class ASTDeclReader;
friend class ASTDeclWriter;
+ friend class ASTNodeImporter;
friend class ASTReader;
friend class CXXClassMemberWrapper;
friend class LinkageComputer;
@@ -318,17 +319,17 @@ protected:
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
unsigned Access : 2;
- /// \brief Whether this declaration was loaded from an AST file.
+ /// Whether this declaration was loaded from an AST file.
unsigned FromASTFile : 1;
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
unsigned IdentifierNamespace : 13;
- /// \brief If 0, we have not computed the linkage of this declaration.
+ /// If 0, we have not computed the linkage of this declaration.
/// Otherwise, it is the linkage + 1.
mutable unsigned CacheValidAndLinkage : 3;
- /// \brief Allocate memory for a deserialized declaration.
+ /// Allocate memory for a deserialized declaration.
///
/// This routine must be used to allocate memory for any declaration that is
/// deserialized from a module file.
@@ -340,7 +341,7 @@ protected:
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.
+ /// Allocate memory for a non-deserialized declaration.
void *operator new(std::size_t Size, const ASTContext &Ctx,
DeclContext *Parent, std::size_t Extra = 0);
@@ -384,7 +385,7 @@ protected:
virtual ~Decl();
- /// \brief Update a potentially out-of-date declaration.
+ /// Update a potentially out-of-date declaration.
void updateOutOfDate(IdentifierInfo &II) const;
Linkage getCachedLinkage() const {
@@ -400,7 +401,7 @@ protected:
}
public:
- /// \brief Source range that this declaration covers.
+ /// Source range that this declaration covers.
virtual SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getLocation(), getLocation());
}
@@ -462,7 +463,7 @@ public:
return AccessSpecifier(Access);
}
- /// \brief Retrieve the access specifier for this declaration, even though
+ /// Retrieve the access specifier for this declaration, even though
/// it may not yet have been properly set.
AccessSpecifier getAccessUnsafe() const {
return AccessSpecifier(Access);
@@ -551,7 +552,7 @@ public:
bool isImplicit() const { return Implicit; }
void setImplicit(bool I = true) { Implicit = I; }
- /// \brief Whether *any* (re-)declaration of the entity was used, meaning that
+ /// Whether *any* (re-)declaration of the entity was used, meaning that
/// a definition is required.
///
/// \param CheckUsedAttr When true, also consider the "used" attribute
@@ -559,28 +560,28 @@ public:
/// whether the function is used.
bool isUsed(bool CheckUsedAttr = true) const;
- /// \brief Set whether the declaration is used, in the sense of odr-use.
+ /// Set whether the declaration is used, in the sense of odr-use.
///
/// This should only be used immediately after creating a declaration.
/// It intentionally doesn't notify any listeners.
void setIsUsed() { getCanonicalDecl()->Used = true; }
- /// \brief Mark the declaration used, in the sense of odr-use.
+ /// Mark the declaration used, in the sense of odr-use.
///
/// This notifies any mutation listeners in addition to setting a bit
/// indicating the declaration is used.
void markUsed(ASTContext &C);
- /// \brief Whether any declaration of this entity was referenced.
+ /// Whether any declaration of this entity was referenced.
bool isReferenced() const;
- /// \brief Whether this declaration was referenced. This should not be relied
+ /// Whether this declaration was referenced. This should not be relied
/// upon for anything other than debugging.
bool isThisDeclarationReferenced() const { return Referenced; }
void setReferenced(bool R = true) { Referenced = R; }
- /// \brief Whether this declaration is a top-level declaration (function,
+ /// Whether this declaration is a top-level declaration (function,
/// global variable, etc.) that is lexically inside an objc container
/// definition.
bool isTopLevelDeclInObjCContainer() const {
@@ -591,17 +592,17 @@ public:
TopLevelDeclInObjCContainer = V;
}
- /// \brief Looks on this and related declarations for an applicable
+ /// Looks on this and related declarations for an applicable
/// external source symbol attribute.
ExternalSourceSymbolAttr *getExternalSourceSymbolAttr() const;
- /// \brief Whether this declaration was marked as being private to the
+ /// Whether this declaration was marked as being private to the
/// module in which it was defined.
bool isModulePrivate() const {
return getModuleOwnershipKind() == ModuleOwnershipKind::ModulePrivate;
}
- /// \brief Whether this declaration is exported (by virtue of being lexically
+ /// Whether this declaration is exported (by virtue of being lexically
/// within an ExportDecl or by being a NamespaceDecl).
bool isExported() const;
@@ -613,7 +614,7 @@ public:
const Attr *getDefiningAttr() const;
protected:
- /// \brief Specify that this declaration was marked as being private
+ /// Specify that this declaration was marked as being private
/// to the module in which it was defined.
void setModulePrivate() {
// The module-private specifier has no effect on unowned declarations.
@@ -623,14 +624,14 @@ protected:
setModuleOwnershipKind(ModuleOwnershipKind::ModulePrivate);
}
- /// \brief Set the owning module ID.
+ /// Set the owning module ID.
void setOwningModuleID(unsigned ID) {
assert(isFromASTFile() && "Only works on a deserialized declaration");
*((unsigned*)this - 2) = ID;
}
public:
- /// \brief Determine the availability of the given declaration.
+ /// Determine the availability of the given declaration.
///
/// This routine will determine the most restrictive availability of
/// the given declaration (e.g., preferring 'unavailable' to
@@ -643,11 +644,16 @@ public:
///
/// \param EnclosingVersion The version to compare with. If empty, assume the
/// deployment target version.
+ ///
+ /// \param RealizedPlatform If non-NULL and the availability result is found
+ /// in an available attribute it will set to the platform which is written in
+ /// the available attribute.
AvailabilityResult
getAvailability(std::string *Message = nullptr,
- VersionTuple EnclosingVersion = VersionTuple()) const;
+ VersionTuple EnclosingVersion = VersionTuple(),
+ StringRef *RealizedPlatform = nullptr) const;
- /// \brief Retrieve the version of the target platform in which this
+ /// Retrieve the version of the target platform in which this
/// declaration was introduced.
///
/// \returns An empty version tuple if this declaration has no 'introduced'
@@ -655,7 +661,7 @@ public:
/// attribute otherwise.
VersionTuple getVersionIntroduced() const;
- /// \brief Determine whether this declaration is marked 'deprecated'.
+ /// 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
@@ -664,7 +670,7 @@ public:
return getAvailability(Message) == AR_Deprecated;
}
- /// \brief Determine whether this declaration is marked 'unavailable'.
+ /// Determine whether this declaration is marked 'unavailable'.
///
/// \param Message If non-NULL and the declaration is unavailable,
/// this will be set to the message describing why the declaration
@@ -673,7 +679,7 @@ public:
return getAvailability(Message) == AR_Unavailable;
}
- /// \brief Determine whether this is a weak-imported symbol.
+ /// Determine whether this is a weak-imported symbol.
///
/// Weak-imported symbols are typically marked with the
/// 'weak_import' attribute, but may also be marked with an
@@ -681,7 +687,7 @@ public:
/// the introduction of this feature.
bool isWeakImported() const;
- /// \brief Determines whether this symbol can be weak-imported,
+ /// Determines whether this symbol can be weak-imported,
/// e.g., whether it would be well-formed to add the weak_import
/// attribute.
///
@@ -689,11 +695,11 @@ public:
/// declaration cannot be weak-imported because it has a definition.
bool canBeWeakImported(bool &IsDefinition) const;
- /// \brief Determine whether this declaration came from an AST file (such as
+ /// Determine whether this declaration came from an AST file (such as
/// a precompiled header or module) rather than having been parsed.
bool isFromASTFile() const { return FromASTFile; }
- /// \brief Retrieve the global declaration ID associated with this
+ /// Retrieve the global declaration ID associated with this
/// declaration, which specifies where this Decl was loaded from.
unsigned getGlobalID() const {
if (isFromASTFile())
@@ -701,7 +707,7 @@ public:
return 0;
}
- /// \brief Retrieve the global ID of the module that owns this particular
+ /// Retrieve the global ID of the module that owns this particular
/// declaration.
unsigned getOwningModuleID() const {
if (isFromASTFile())
@@ -716,7 +722,7 @@ protected:
bool hasLocalOwningModuleStorage() const;
public:
- /// \brief Get the imported owning module, if this decl is from an imported
+ /// Get the imported owning module, if this decl is from an imported
/// (non-local) module.
Module *getImportedOwningModule() const {
if (!isFromASTFile() || !hasOwningModule())
@@ -725,7 +731,7 @@ public:
return getOwningModuleSlow();
}
- /// \brief Get the local owning module, if known. Returns nullptr if owner is
+ /// Get the local owning module, if known. Returns nullptr if owner is
/// not yet known or declaration is not from a module.
Module *getLocalOwningModule() const {
if (isFromASTFile() || !hasOwningModule())
@@ -759,7 +765,7 @@ public:
/// all declarations in a global module fragment are unowned.
Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const;
- /// \brief Determine whether this declaration might be hidden from name
+ /// Determine whether this declaration might be hidden from name
/// lookup. Note that the declaration might be visible even if this returns
/// \c false, if the owning module is visible within the query context.
// FIXME: Rename this to make it clearer what it does.
@@ -774,12 +780,12 @@ public:
setModuleOwnershipKind(ModuleOwnershipKind::Visible);
}
- /// \brief Get the kind of module ownership for this declaration.
+ /// Get the kind of module ownership for this declaration.
ModuleOwnershipKind getModuleOwnershipKind() const {
return NextInContextAndBits.getInt();
}
- /// \brief Set whether this declaration is hidden from name lookup.
+ /// Set whether this declaration is hidden from name lookup.
void setModuleOwnershipKind(ModuleOwnershipKind MOK) {
assert(!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned &&
MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() &&
@@ -836,6 +842,10 @@ public:
void setLexicalDeclContext(DeclContext *DC);
+ /// Determine whether this declaration is a templated entity (whether it is
+ // within the scope of a template parameter).
+ bool isTemplated() const;
+
/// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
/// scoped decl is defined outside the current function or method. This is
/// roughly global variables and functions, but also handles enums (which
@@ -844,7 +854,7 @@ public:
return getParentFunctionOrMethod() == nullptr;
}
- /// \brief Returns true if this declaration lexically is inside a function.
+ /// Returns true if this declaration lexically is inside a function.
/// It recognizes non-defining declarations as well as members of local
/// classes:
/// \code
@@ -853,7 +863,7 @@ public:
/// \endcode
bool isLexicallyWithinFunctionOrMethod() const;
- /// \brief If this decl is defined inside a function/method/block it returns
+ /// If this decl is defined inside a function/method/block it returns
/// the corresponding DeclContext, otherwise it returns null.
const DeclContext *getParentFunctionOrMethod() const;
DeclContext *getParentFunctionOrMethod() {
@@ -861,32 +871,32 @@ public:
const_cast<const Decl*>(this)->getParentFunctionOrMethod());
}
- /// \brief Retrieves the "canonical" declaration of the given declaration.
+ /// Retrieves the "canonical" declaration of the given declaration.
virtual Decl *getCanonicalDecl() { return this; }
const Decl *getCanonicalDecl() const {
return const_cast<Decl*>(this)->getCanonicalDecl();
}
- /// \brief Whether this particular Decl is a canonical one.
+ /// Whether this particular Decl is a canonical one.
bool isCanonicalDecl() const { return getCanonicalDecl() == this; }
protected:
- /// \brief Returns the next redeclaration or itself if this is the only decl.
+ /// Returns the next redeclaration or itself if this is the only decl.
///
/// Decl subclasses that can be redeclared should override this method so that
/// Decl::redecl_iterator can iterate over them.
virtual Decl *getNextRedeclarationImpl() { return this; }
- /// \brief Implementation of getPreviousDecl(), to be overridden by any
+ /// Implementation of getPreviousDecl(), to be overridden by any
/// subclass that has a redeclaration chain.
virtual Decl *getPreviousDeclImpl() { return nullptr; }
- /// \brief Implementation of getMostRecentDecl(), to be overridden by any
+ /// Implementation of getMostRecentDecl(), to be overridden by any
/// subclass that has a redeclaration chain.
virtual Decl *getMostRecentDeclImpl() { return this; }
public:
- /// \brief Iterates through all the redeclarations of the same decl.
+ /// Iterates through all the redeclarations of the same decl.
class redecl_iterator {
/// Current - The current declaration.
Decl *Current = nullptr;
@@ -931,7 +941,7 @@ public:
using redecl_range = llvm::iterator_range<redecl_iterator>;
- /// \brief Returns an iterator range for all the redeclarations of the same
+ /// 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());
@@ -943,26 +953,26 @@ public:
redecl_iterator redecls_end() const { return redecl_iterator(); }
- /// \brief Retrieve the previous declaration that declares the same entity
+ /// Retrieve the previous declaration that declares the same entity
/// as this declaration, or NULL if there is no previous declaration.
Decl *getPreviousDecl() { return getPreviousDeclImpl(); }
- /// \brief Retrieve the most recent declaration that declares the same entity
+ /// Retrieve the most recent declaration that declares the same entity
/// as this declaration, or NULL if there is no previous declaration.
const Decl *getPreviousDecl() const {
return const_cast<Decl *>(this)->getPreviousDeclImpl();
}
- /// \brief True if this is the first declaration in its redeclaration chain.
+ /// True if this is the first declaration in its redeclaration chain.
bool isFirstDecl() const {
return getPreviousDecl() == nullptr;
}
- /// \brief Retrieve the most recent declaration that declares the same entity
+ /// Retrieve the most recent declaration that declares the same entity
/// as this declaration (which may be this declaration).
Decl *getMostRecentDecl() { return getMostRecentDeclImpl(); }
- /// \brief Retrieve the most recent declaration that declares the same entity
+ /// Retrieve the most recent declaration that declares the same entity
/// as this declaration (which may be this declaration).
const Decl *getMostRecentDecl() const {
return const_cast<Decl *>(this)->getMostRecentDeclImpl();
@@ -973,7 +983,7 @@ public:
/// top-level Stmt* of that body. Otherwise this method returns null.
virtual Stmt* getBody() const { return nullptr; }
- /// \brief Returns true if this \c Decl represents a declaration for a body of
+ /// 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.
@@ -996,24 +1006,24 @@ public:
/// template parameter pack.
bool isTemplateParameterPack() const;
- /// \brief Whether this declaration is a parameter pack.
+ /// Whether this declaration is a parameter pack.
bool isParameterPack() const;
- /// \brief returns true if this declaration is a template
+ /// returns true if this declaration is a template
bool isTemplateDecl() const;
- /// \brief Whether this declaration is a function or function template.
+ /// Whether this declaration is a function or function template.
bool isFunctionOrFunctionTemplate() const {
return (DeclKind >= Decl::firstFunction &&
DeclKind <= Decl::lastFunction) ||
DeclKind == FunctionTemplate;
}
- /// \brief If this is a declaration that describes some template, this
+ /// If this is a declaration that describes some template, this
/// method returns that template declaration.
TemplateDecl *getDescribedTemplate() const;
- /// \brief Returns the function itself, or the templated function if this is a
+ /// Returns the function itself, or the templated function if this is a
/// function template.
FunctionDecl *getAsFunction() LLVM_READONLY;
@@ -1021,7 +1031,7 @@ public:
return const_cast<Decl *>(this)->getAsFunction();
}
- /// \brief Changes the namespace of this declaration to reflect that it's
+ /// Changes the namespace of this declaration to reflect that it's
/// a function-local extern declaration.
///
/// These declarations appear in the lexical context of the extern
@@ -1042,14 +1052,14 @@ public:
IdentifierNamespace |= IDNS_Ordinary;
}
- /// \brief Determine whether this is a block-scope declaration with linkage.
+ /// Determine whether this is a block-scope declaration with linkage.
/// This will either be a local variable declaration declared 'extern', or a
/// local function declaration.
bool isLocalExternDecl() {
return IdentifierNamespace & IDNS_LocalExtern;
}
- /// \brief Changes the namespace of this declaration to reflect that it's
+ /// Changes the namespace of this declaration to reflect that it's
/// the object of a friend declaration.
///
/// These declarations appear in the lexical context of the friending
@@ -1091,7 +1101,7 @@ public:
FOK_Undeclared ///< A friend of a previously-undeclared entity.
};
- /// \brief Determines whether this declaration is the object of a
+ /// Determines whether this declaration is the object of a
/// friend declaration and, if so, what kind.
///
/// There is currently no direct way to find the associated FriendDecl.
@@ -1131,7 +1141,7 @@ public:
void dump(raw_ostream &Out, bool Deserialize = false) const;
- /// \brief Looks through the Decl's underlying type to extract a FunctionType
+ /// 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;
@@ -1145,7 +1155,7 @@ protected:
ASTMutationListener *getASTMutationListener() const;
};
-/// \brief Determine whether two declarations declare the same entity.
+/// Determine whether two declarations declare the same entity.
inline bool declaresSameEntity(const Decl *D1, const Decl *D2) {
if (!D1 || !D2)
return false;
@@ -1172,7 +1182,7 @@ public:
void print(raw_ostream &OS) const override;
};
-/// \brief The results of name lookup within a DeclContext. This is either a
+/// The results of name lookup within a DeclContext. This is either a
/// single result (with no stable storage) or a collection of results (with
/// stable storage provided by the lookup table).
class DeclContextLookupResult {
@@ -1253,36 +1263,36 @@ class DeclContext {
/// DeclKind - This indicates which class this is.
unsigned DeclKind : 8;
- /// \brief Whether this declaration context also has some external
+ /// Whether this declaration context also has some external
/// storage that contains additional declarations that are lexically
/// part of this context.
mutable bool ExternalLexicalStorage : 1;
- /// \brief Whether this declaration context also has some external
+ /// Whether this declaration context also has some external
/// storage that contains additional declarations that are visible
/// in this context.
mutable bool ExternalVisibleStorage : 1;
- /// \brief Whether this declaration context has had external visible
+ /// Whether this declaration context has had external visible
/// storage added since the last lookup. In this case, \c LookupPtr's
/// invariant may not hold and needs to be fixed before we perform
/// another lookup.
mutable bool NeedToReconcileExternalVisibleStorage : 1;
- /// \brief If \c true, this context may have local lexical declarations
+ /// If \c true, this context may have local lexical declarations
/// that are missing from the lookup table.
mutable bool HasLazyLocalLexicalLookups : 1;
- /// \brief If \c true, the external source may have lexical declarations
+ /// If \c true, the external source may have lexical declarations
/// that are missing from the lookup table.
mutable bool HasLazyExternalLexicalLookups : 1;
- /// \brief If \c true, lookups should only return identifier from
+ /// If \c true, lookups should only return identifier from
/// DeclContext scope (for example TranslationUnit). Used in
/// LookupQualifiedName()
mutable bool UseQualifiedLookup : 1;
- /// \brief Pointer to the data structure used to lookup declarations
+ /// Pointer to the data structure used to lookup declarations
/// within this context (or a DependentStoredDeclsMap if this is a
/// dependent context). We maintain the invariant that, if the map
/// contains an entry for a DeclarationName (and we haven't lazily
@@ -1305,7 +1315,7 @@ protected:
/// another pointer.
mutable Decl *LastDecl = nullptr;
- /// \brief Build up a chain of declarations.
+ /// Build up a chain of declarations.
///
/// \returns the first/last pair of declarations.
static std::pair<Decl *, Decl *>
@@ -1388,7 +1398,7 @@ public:
}
}
- /// \brief Test whether the context supports looking up names.
+ /// Test whether the context supports looking up names.
bool isLookupContext() const {
return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec &&
DeclKind != Decl::Export;
@@ -1414,7 +1424,7 @@ public:
bool isInlineNamespace() const;
- /// \brief Determines whether this context is dependent on a
+ /// Determines whether this context is dependent on a
/// template parameter.
bool isDependentContext() const;
@@ -1435,28 +1445,28 @@ public:
/// C++0x scoped enums), and C++ linkage specifications.
bool isTransparentContext() const;
- /// \brief Determines whether this context or some of its ancestors is a
+ /// Determines whether this context or some of its ancestors is a
/// linkage specification context that specifies C linkage.
bool isExternCContext() const;
- /// \brief Retrieve the nearest enclosing C linkage specification context.
+ /// Retrieve the nearest enclosing C linkage specification context.
const LinkageSpecDecl *getExternCContext() const;
- /// \brief Determines whether this context or some of its ancestors is a
+ /// Determines whether this context or some of its ancestors is a
/// linkage specification context that specifies C++ linkage.
bool isExternCXXContext() const;
- /// \brief Determine whether this declaration context is equivalent
+ /// Determine whether this declaration context is equivalent
/// to the declaration context DC.
bool Equals(const DeclContext *DC) const {
return DC && this->getPrimaryContext() == DC->getPrimaryContext();
}
- /// \brief Determine whether this declaration context encloses the
+ /// Determine whether this declaration context encloses the
/// declaration context DC.
bool Encloses(const DeclContext *DC) const;
- /// \brief Find the nearest non-closure ancestor of this context,
+ /// Find the nearest non-closure ancestor of this context,
/// i.e. the innermost semantic parent of this context which is not
/// a closure. A context may be its own non-closure ancestor.
Decl *getNonClosureAncestor();
@@ -1483,19 +1493,19 @@ public:
return const_cast<DeclContext *>(this)->getRedeclContext();
}
- /// \brief Retrieve the nearest enclosing namespace context.
+ /// Retrieve the nearest enclosing namespace context.
DeclContext *getEnclosingNamespaceContext();
const DeclContext *getEnclosingNamespaceContext() const {
return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
}
- /// \brief Retrieve the outermost lexically enclosing record context.
+ /// Retrieve the outermost lexically enclosing record context.
RecordDecl *getOuterLexicalRecordContext();
const RecordDecl *getOuterLexicalRecordContext() const {
return const_cast<DeclContext *>(this)->getOuterLexicalRecordContext();
}
- /// \brief Test if this context is part of the enclosing namespace set of
+ /// Test if this context is part of the enclosing namespace set of
/// the context NS, as defined in C++0x [namespace.def]p9. If either context
/// isn't a namespace, this is equivalent to Equals().
///
@@ -1503,7 +1513,7 @@ public:
/// inline, its enclosing namespace, recursively.
bool InEnclosingNamespaceSetOf(const DeclContext *NS) const;
- /// \brief Collects all of the declaration contexts that are semantically
+ /// Collects all of the declaration contexts that are semantically
/// connected to this declaration context.
///
/// For declaration contexts that have multiple semantically connected but
@@ -1659,7 +1669,7 @@ public:
}
};
- /// \brief Iterates over a filtered subrange of declarations stored
+ /// Iterates over a filtered subrange of declarations stored
/// in a DeclContext.
///
/// This iterator visits only those declarations that are of type
@@ -1735,7 +1745,7 @@ public:
}
};
- /// @brief Add the declaration D into this context.
+ /// Add the declaration D into this context.
///
/// This routine should be invoked when the declaration D has first
/// been declared, to place D into the context where it was
@@ -1749,7 +1759,7 @@ public:
/// semantic context via makeDeclVisibleInContext.
void addDecl(Decl *D);
- /// @brief Add the declaration D into this context, but suppress
+ /// Add the declaration D into this context, but suppress
/// searches for external declarations with the same name.
///
/// Although analogous in function to addDecl, this removes an
@@ -1759,7 +1769,7 @@ public:
/// See the ASTImporter for use cases.
void addDeclInternal(Decl *D);
- /// @brief Add the declaration D to this context without modifying
+ /// Add the declaration D to this context without modifying
/// any lookup tables.
///
/// This is useful for some operations in dependent contexts where
@@ -1767,12 +1777,16 @@ public:
/// only happens with friends.
void addHiddenDecl(Decl *D);
- /// @brief Removes a declaration from this context.
+ /// Removes a declaration from this context.
void removeDecl(Decl *D);
-
- /// @brief Checks whether a declaration is in this context.
+
+ /// Checks whether a declaration is in this context.
bool containsDecl(Decl *D) const;
+ /// Checks whether a declaration is in this context.
+ /// This also loads the Decls from the external source before the check.
+ bool containsDeclAndLoad(Decl *D) const;
+
using lookup_result = DeclContextLookupResult;
using lookup_iterator = lookup_result::iterator;
@@ -1783,12 +1797,12 @@ public:
/// routine will not look into parent contexts.
lookup_result lookup(DeclarationName Name) const;
- /// \brief Find the declarations with the given name that are visible
+ /// Find the declarations with the given name that are visible
/// within this context; don't attempt to retrieve anything from an
/// external source.
lookup_result noload_lookup(DeclarationName Name);
- /// \brief A simplistic name lookup mechanism that performs name lookup
+ /// A simplistic name lookup mechanism that performs name lookup
/// into this declaration context without consulting the external source.
///
/// This function should almost never be used, because it subverts the
@@ -1800,7 +1814,7 @@ public:
void localUncachedLookup(DeclarationName Name,
SmallVectorImpl<NamedDecl *> &Results);
- /// @brief Makes a declaration visible within this context.
+ /// Makes a declaration visible within this context.
///
/// This routine makes the declaration D visible to name lookup
/// within this context and, if this is a transparent context,
@@ -1823,13 +1837,15 @@ public:
using lookups_range = llvm::iterator_range<all_lookups_iterator>;
lookups_range lookups() const;
- lookups_range noload_lookups() const;
+ // Like lookups(), but avoids loading external declarations.
+ // If PreserveInternalState, avoids building lookup data structures too.
+ lookups_range noload_lookups(bool PreserveInternalState) const;
- /// \brief Iterators over all possible lookups within this context.
+ /// Iterators over all possible lookups within this context.
all_lookups_iterator lookups_begin() const;
all_lookups_iterator lookups_end() const;
- /// \brief Iterators over all possible lookups within this context that are
+ /// Iterators over all possible lookups within this context that are
/// currently loaded; don't attempt to retrieve anything from an external
/// source.
all_lookups_iterator noload_lookups_begin() const;
@@ -1861,7 +1877,7 @@ public:
// Low-level accessors
- /// \brief Mark that there are external lexical declarations that we need
+ /// Mark that there are external lexical declarations that we need
/// to include in our lookup table (and that are not available as external
/// visible lookups). These extra lookup results will be found by walking
/// the lexical declarations of this context. This should be used only if
@@ -1873,28 +1889,28 @@ public:
HasLazyExternalLexicalLookups = true;
}
- /// \brief Retrieve the internal representation of the lookup structure.
+ /// Retrieve the internal representation of the lookup structure.
/// This may omit some names if we are lazily building the structure.
StoredDeclsMap *getLookupPtr() const { return LookupPtr; }
- /// \brief Ensure the lookup structure is fully-built and return it.
+ /// Ensure the lookup structure is fully-built and return it.
StoredDeclsMap *buildLookup();
- /// \brief Whether this DeclContext has external storage containing
+ /// Whether this DeclContext has external storage containing
/// additional declarations that are lexically in this context.
bool hasExternalLexicalStorage() const { return ExternalLexicalStorage; }
- /// \brief State whether this DeclContext has external storage for
+ /// State whether this DeclContext has external storage for
/// declarations lexically in this context.
void setHasExternalLexicalStorage(bool ES = true) {
ExternalLexicalStorage = ES;
}
- /// \brief Whether this DeclContext has external storage containing
+ /// Whether this DeclContext has external storage containing
/// additional declarations that are visible in this context.
bool hasExternalVisibleStorage() const { return ExternalVisibleStorage; }
- /// \brief State whether this DeclContext has external storage for
+ /// State whether this DeclContext has external storage for
/// declarations visible in this context.
void setHasExternalVisibleStorage(bool ES = true) {
ExternalVisibleStorage = ES;
@@ -1902,7 +1918,7 @@ public:
NeedToReconcileExternalVisibleStorage = true;
}
- /// \brief Determine whether the given declaration is stored in the list of
+ /// Determine whether the given declaration is stored in the list of
/// declarations lexically within this context.
bool isDeclInLexicalTraversal(const Decl *D) const {
return D && (D->NextInContextAndBits.getPointer() || D == FirstDecl ||
@@ -1933,7 +1949,7 @@ private:
void reconcileExternalVisibleStorage() const;
bool LoadLexicalDeclsFromExternalStorage() const;
- /// @brief Makes a declaration visible within this context, but
+ /// Makes a declaration visible within this context, but
/// suppresses searches for external declarations with the same
/// name.
///
@@ -1943,6 +1959,7 @@ private:
StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
+ void loadLazyLocalLexicalLookups();
void buildLookupImpl(DeclContext *DCtx, bool Internal);
void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
bool Rediscoverable);
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 88dc9a6559172..1d0489912c6bd 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Defines the C++ Decl subclasses, other than those for templates
+/// Defines the C++ Decl subclasses, other than those for templates
/// (found in DeclTemplate.h) and friends (in DeclFriend.h).
//
//===----------------------------------------------------------------------===//
@@ -20,6 +20,7 @@
#include "clang/AST/ASTUnresolvedSet.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExternalASTSource.h"
@@ -72,7 +73,7 @@ class TemplateDecl;
class TemplateParameterList;
class UsingDecl;
-/// \brief Represents any kind of function declaration, whether it is a
+/// Represents any kind of function declaration, whether it is a
/// concrete function or a function template.
class AnyFunctionDecl {
NamedDecl *Function;
@@ -83,11 +84,11 @@ public:
AnyFunctionDecl(FunctionDecl *FD) : Function(FD) {}
AnyFunctionDecl(FunctionTemplateDecl *FTD);
- /// \brief Implicily converts any function or function template into a
+ /// Implicily converts any function or function template into a
/// named declaration.
operator NamedDecl *() const { return Function; }
- /// \brief Retrieve the underlying function or function template.
+ /// Retrieve the underlying function or function template.
NamedDecl *get() const { return Function; }
static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) {
@@ -118,7 +119,7 @@ namespace llvm {
namespace clang {
-/// \brief Represents an access specifier followed by colon ':'.
+/// Represents an access specifier followed by colon ':'.
///
/// An objects of this class represents sugar for the syntactic occurrence
/// of an access specifier followed by a colon in the list of member
@@ -129,7 +130,7 @@ namespace clang {
/// Also note that this class has nothing to do with so-called
/// "access declarations" (C++98 11.3 [class.access.dcl]).
class AccessSpecDecl : public Decl {
- /// \brief The location of the ':'.
+ /// The location of the ':'.
SourceLocation ColonLoc;
AccessSpecDecl(AccessSpecifier AS, DeclContext *DC,
@@ -143,16 +144,16 @@ class AccessSpecDecl : public Decl {
virtual void anchor();
public:
- /// \brief The location of the access specifier.
+ /// The location of the access specifier.
SourceLocation getAccessSpecifierLoc() const { return getLocation(); }
- /// \brief Sets the location of the access specifier.
+ /// Sets the location of the access specifier.
void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); }
- /// \brief The location of the colon following the access specifier.
+ /// The location of the colon following the access specifier.
SourceLocation getColonLoc() const { return ColonLoc; }
- /// \brief Sets the location of the colon.
+ /// Sets the location of the colon.
void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
SourceRange getSourceRange() const override LLVM_READONLY {
@@ -172,7 +173,7 @@ public:
static bool classofKind(Kind K) { return K == AccessSpec; }
};
-/// \brief Represents a base class of a C++ class.
+/// Represents a base class of a C++ class.
///
/// Each CXXBaseSpecifier represents a single, direct base class (or
/// struct) of a C++ class (or struct). It specifies the type of that
@@ -189,35 +190,35 @@ public:
/// In this code, C will have two CXXBaseSpecifiers, one for "public
/// virtual A" and the other for "protected B".
class CXXBaseSpecifier {
- /// \brief The source code range that covers the full base
+ /// The source code range that covers the full base
/// specifier, including the "virtual" (if present) and access
/// specifier (if present).
SourceRange Range;
- /// \brief The source location of the ellipsis, if this is a pack
+ /// The source location of the ellipsis, if this is a pack
/// expansion.
SourceLocation EllipsisLoc;
- /// \brief Whether this is a virtual base class or not.
+ /// Whether this is a virtual base class or not.
unsigned Virtual : 1;
- /// \brief Whether this is the base of a class (true) or of a struct (false).
+ /// Whether this is the base of a class (true) or of a struct (false).
///
/// This determines the mapping from the access specifier as written in the
/// source code to the access specifier used for semantic analysis.
unsigned BaseOfClass : 1;
- /// \brief Access specifier as written in the source code (may be AS_none).
+ /// Access specifier as written in the source code (may be AS_none).
///
/// The actual type of data stored here is an AccessSpecifier, but we use
/// "unsigned" here to work around a VC++ bug.
unsigned Access : 2;
- /// \brief Whether the class contains a using declaration
+ /// Whether the class contains a using declaration
/// to inherit the named class's constructors.
unsigned InheritConstructors : 1;
- /// \brief The type of the base class.
+ /// The type of the base class.
///
/// This will be a class or struct (or a typedef of such). The source code
/// range does not include the \c virtual or the access specifier.
@@ -230,40 +231,40 @@ public:
: Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC),
Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) {}
- /// \brief Retrieves the source range that contains the entire base specifier.
+ /// Retrieves the source range that contains the entire base specifier.
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- /// \brief Get the location at which the base class type was written.
+ /// Get the location at which the base class type was written.
SourceLocation getBaseTypeLoc() const LLVM_READONLY {
return BaseTypeInfo->getTypeLoc().getLocStart();
}
- /// \brief Determines whether the base class is a virtual base class (or not).
+ /// Determines whether the base class is a virtual base class (or not).
bool isVirtual() const { return Virtual; }
- /// \brief Determine whether this base class is a base of a class declared
+ /// Determine whether this base class is a base of a class declared
/// with the 'class' keyword (vs. one declared with the 'struct' keyword).
bool isBaseOfClass() const { return BaseOfClass; }
- /// \brief Determine whether this base specifier is a pack expansion.
+ /// Determine whether this base specifier is a pack expansion.
bool isPackExpansion() const { return EllipsisLoc.isValid(); }
- /// \brief Determine whether this base class's constructors get inherited.
+ /// Determine whether this base class's constructors get inherited.
bool getInheritConstructors() const { return InheritConstructors; }
- /// \brief Set that this base class's constructors should be inherited.
+ /// Set that this base class's constructors should be inherited.
void setInheritConstructors(bool Inherit = true) {
InheritConstructors = Inherit;
}
- /// \brief For a pack expansion, determine the location of the ellipsis.
+ /// For a pack expansion, determine the location of the ellipsis.
SourceLocation getEllipsisLoc() const {
return EllipsisLoc;
}
- /// \brief Returns the access specifier for this base specifier.
+ /// Returns the access specifier for this base specifier.
///
/// This is the actual base specifier as used for semantic analysis, so
/// the result can never be AS_none. To retrieve the access specifier as
@@ -275,7 +276,7 @@ public:
return (AccessSpecifier)Access;
}
- /// \brief Retrieves the access specifier as written in the source code
+ /// Retrieves the access specifier as written in the source code
/// (which may mean that no access specifier was explicitly written).
///
/// Use getAccessSpecifier() to retrieve the access specifier for use in
@@ -284,18 +285,18 @@ public:
return (AccessSpecifier)Access;
}
- /// \brief Retrieves the type of the base class.
+ /// Retrieves the type of the base class.
///
/// This type will always be an unqualified class type.
QualType getType() const {
return BaseTypeInfo->getType().getUnqualifiedType();
}
- /// \brief Retrieves the type and source location of the base class.
+ /// Retrieves the type and source location of the base class.
TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
};
-/// \brief Represents a C++ struct/union/class.
+/// Represents a C++ struct/union/class.
class CXXRecordDecl : public RecordDecl {
friend class ASTDeclReader;
friend class ASTDeclWriter;
@@ -321,16 +322,16 @@ class CXXRecordDecl : public RecordDecl {
};
struct DefinitionData {
- /// \brief True if this class has any user-declared constructors.
+ /// True if this class has any user-declared constructors.
unsigned UserDeclaredConstructor : 1;
- /// \brief The user-declared special members which this class has.
+ /// The user-declared special members which this class has.
unsigned UserDeclaredSpecialMembers : 6;
- /// \brief True when this class is an aggregate.
+ /// True when this class is an aggregate.
unsigned Aggregate : 1;
- /// \brief True when this class is a POD-type.
+ /// True when this class is a POD-type.
unsigned PlainOldData : 1;
/// true when this class is empty for traits purposes,
@@ -339,15 +340,20 @@ class CXXRecordDecl : public RecordDecl {
/// class. Doesn't take union-ness into account.
unsigned Empty : 1;
- /// \brief True when this class is polymorphic, i.e., has at
+ /// True when this class is polymorphic, i.e., has at
/// least one virtual member or derives from a polymorphic class.
unsigned Polymorphic : 1;
- /// \brief True when this class is abstract, i.e., has at least
+ /// True when this class is abstract, i.e., has at least
/// one pure virtual function, (that can come from a base class).
unsigned Abstract : 1;
- /// \brief True when this class has standard layout.
+ /// True when this class is standard-layout, per the applicable
+ /// language rules (including DRs).
+ unsigned IsStandardLayout : 1;
+
+ /// True when this class was standard-layout under the C++11
+ /// definition.
///
/// C++11 [class]p7. A standard-layout class is a class that:
/// * has no non-static data members of type non-standard-layout class (or
@@ -361,57 +367,63 @@ class CXXRecordDecl : public RecordDecl {
/// classes with non-static data members, and
/// * has no base classes of the same type as the first non-static data
/// member.
- unsigned IsStandardLayout : 1;
+ unsigned IsCXX11StandardLayout : 1;
- /// \brief True when there are no non-empty base classes.
- ///
+ /// True when any base class has any declared non-static data
+ /// members or bit-fields.
/// This is a helper bit of state used to implement IsStandardLayout more
/// efficiently.
- unsigned HasNoNonEmptyBases : 1;
+ unsigned HasBasesWithFields : 1;
+
+ /// True when any base class has any declared non-static data
+ /// members.
+ /// This is a helper bit of state used to implement IsCXX11StandardLayout
+ /// more efficiently.
+ unsigned HasBasesWithNonStaticDataMembers : 1;
- /// \brief True when there are private non-static data members.
+ /// True when there are private non-static data members.
unsigned HasPrivateFields : 1;
- /// \brief True when there are protected non-static data members.
+ /// True when there are protected non-static data members.
unsigned HasProtectedFields : 1;
- /// \brief True when there are private non-static data members.
+ /// True when there are private non-static data members.
unsigned HasPublicFields : 1;
- /// \brief True if this class (or any subobject) has mutable fields.
+ /// True if this class (or any subobject) has mutable fields.
unsigned HasMutableFields : 1;
- /// \brief True if this class (or any nested anonymous struct or union)
+ /// True if this class (or any nested anonymous struct or union)
/// has variant members.
unsigned HasVariantMembers : 1;
- /// \brief True if there no non-field members declared by the user.
+ /// True if there no non-field members declared by the user.
unsigned HasOnlyCMembers : 1;
- /// \brief True if any field has an in-class initializer, including those
+ /// True if any field has an in-class initializer, including those
/// within anonymous unions or structs.
unsigned HasInClassInitializer : 1;
- /// \brief True if any field is of reference type, and does not have an
+ /// True if any field is of reference type, and does not have an
/// in-class initializer.
///
/// In this case, value-initialization of this class is illegal in C++98
/// even if the class has a trivial default constructor.
unsigned HasUninitializedReferenceMember : 1;
- /// \brief True if any non-mutable field whose type doesn't have a user-
+ /// True if any non-mutable field whose type doesn't have a user-
/// provided default ctor also doesn't have an in-class initializer.
unsigned HasUninitializedFields : 1;
- /// \brief True if there are any member using-declarations that inherit
+ /// True if there are any member using-declarations that inherit
/// constructors from a base class.
unsigned HasInheritedConstructor : 1;
- /// \brief True if there are any member using-declarations named
+ /// True if there are any member using-declarations named
/// 'operator='.
unsigned HasInheritedAssignment : 1;
- /// \brief These flags are \c true if a defaulted corresponding special
+ /// These flags are \c true if a defaulted corresponding special
/// member can't be fully analyzed without performing overload resolution.
/// @{
unsigned NeedOverloadResolutionForCopyConstructor : 1;
@@ -420,7 +432,7 @@ class CXXRecordDecl : public RecordDecl {
unsigned NeedOverloadResolutionForDestructor : 1;
/// @}
- /// \brief These flags are \c true if an implicit defaulted corresponding
+ /// These flags are \c true if an implicit defaulted corresponding
/// special member would be defined as deleted.
/// @{
unsigned DefaultedCopyConstructorIsDeleted : 1;
@@ -429,7 +441,7 @@ class CXXRecordDecl : public RecordDecl {
unsigned DefaultedDestructorIsDeleted : 1;
/// @}
- /// \brief The trivial special members which this class has, per
+ /// The trivial special members which this class has, per
/// C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25,
/// C++11 [class.dtor]p5, or would have if the member were not suppressed.
///
@@ -437,7 +449,12 @@ class CXXRecordDecl : public RecordDecl {
/// which have been declared but not yet defined.
unsigned HasTrivialSpecialMembers : 6;
- /// \brief The declared special members of this class which are known to be
+ /// These bits keep track of the triviality of special functions for the
+ /// purpose of calls. Only the bits corresponding to SMF_CopyConstructor,
+ /// SMF_MoveConstructor, and SMF_Destructor are meaningful here.
+ unsigned HasTrivialSpecialMembersForCall : 6;
+
+ /// The declared special members of this class which are known to be
/// non-trivial.
///
/// This excludes any user-declared but not user-provided special members
@@ -445,108 +462,108 @@ class CXXRecordDecl : public RecordDecl {
/// members which have not yet been declared.
unsigned DeclaredNonTrivialSpecialMembers : 6;
- /// \brief True when this class has a destructor with no semantic effect.
+ /// These bits keep track of the declared special members that are
+ /// non-trivial for the purpose of calls.
+ /// Only the bits corresponding to SMF_CopyConstructor,
+ /// SMF_MoveConstructor, and SMF_Destructor are meaningful here.
+ unsigned DeclaredNonTrivialSpecialMembersForCall : 6;
+
+ /// True when this class has a destructor with no semantic effect.
unsigned HasIrrelevantDestructor : 1;
- /// \brief True when this class has at least one user-declared constexpr
+ /// True when this class has at least one user-declared constexpr
/// constructor which is neither the copy nor move constructor.
unsigned HasConstexprNonCopyMoveConstructor : 1;
- /// \brief True if this class has a (possibly implicit) defaulted default
+ /// True if this class has a (possibly implicit) defaulted default
/// constructor.
unsigned HasDefaultedDefaultConstructor : 1;
- /// \brief True if this class can be passed in a non-address-preserving
- /// fashion (such as in registers) according to the C++ language rules.
- /// This does not imply anything about how the ABI in use will actually
- /// pass an object of this class.
- unsigned CanPassInRegisters : 1;
-
- /// \brief True if a defaulted default constructor for this class would
+ /// True if a defaulted default constructor for this class would
/// be constexpr.
unsigned DefaultedDefaultConstructorIsConstexpr : 1;
- /// \brief True if this class has a constexpr default constructor.
+ /// 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.
unsigned HasConstexprDefaultConstructor : 1;
- /// \brief True when this class contains at least one non-static data
+ /// True when this class contains at least one non-static data
/// member or base class of non-literal or volatile type.
unsigned HasNonLiteralTypeFieldsOrBases : 1;
- /// \brief True when visible conversion functions are already computed
+ /// True when visible conversion functions are already computed
/// and are available.
unsigned ComputedVisibleConversions : 1;
- /// \brief Whether we have a C++11 user-provided default constructor (not
+ /// Whether we have a C++11 user-provided default constructor (not
/// explicitly deleted or defaulted).
unsigned UserProvidedDefaultConstructor : 1;
- /// \brief The special members which have been declared for this class,
+ /// The special members which have been declared for this class,
/// either by the user or implicitly.
unsigned DeclaredSpecialMembers : 6;
- /// \brief Whether an implicit copy constructor could have a const-qualified
+ /// Whether an implicit copy constructor could have a const-qualified
/// parameter, for initializing virtual bases and for other subobjects.
unsigned ImplicitCopyConstructorCanHaveConstParamForVBase : 1;
unsigned ImplicitCopyConstructorCanHaveConstParamForNonVBase : 1;
- /// \brief Whether an implicit copy assignment operator would have a
+ /// Whether an implicit copy assignment operator would have a
/// const-qualified parameter.
unsigned ImplicitCopyAssignmentHasConstParam : 1;
- /// \brief Whether any declared copy constructor has a const-qualified
+ /// Whether any declared copy constructor has a const-qualified
/// parameter.
unsigned HasDeclaredCopyConstructorWithConstParam : 1;
- /// \brief Whether any declared copy assignment operator has either a
+ /// Whether any declared copy assignment operator has either a
/// const-qualified reference parameter or a non-reference parameter.
unsigned HasDeclaredCopyAssignmentWithConstParam : 1;
- /// \brief Whether this class describes a C++ lambda.
+ /// Whether this class describes a C++ lambda.
unsigned IsLambda : 1;
- /// \brief Whether we are currently parsing base specifiers.
+ /// Whether we are currently parsing base specifiers.
unsigned IsParsingBaseSpecifiers : 1;
unsigned HasODRHash : 1;
- /// \brief A hash of parts of the class to help in ODR checking.
+ /// A hash of parts of the class to help in ODR checking.
unsigned ODRHash = 0;
- /// \brief The number of base class specifiers in Bases.
+ /// The number of base class specifiers in Bases.
unsigned NumBases = 0;
- /// \brief The number of virtual base class specifiers in VBases.
+ /// The number of virtual base class specifiers in VBases.
unsigned NumVBases = 0;
- /// \brief Base classes of this class.
+ /// Base classes of this class.
///
/// FIXME: This is wasted space for a union.
LazyCXXBaseSpecifiersPtr Bases;
- /// \brief direct and indirect virtual base classes of this class.
+ /// direct and indirect virtual base classes of this class.
LazyCXXBaseSpecifiersPtr VBases;
- /// \brief The conversion functions of this C++ class (but not its
+ /// The conversion functions of this C++ class (but not its
/// inherited conversion functions).
///
/// Each of the entries in this overload set is a CXXConversionDecl.
LazyASTUnresolvedSet Conversions;
- /// \brief The conversion functions of this C++ class and all those
+ /// The conversion functions of this C++ class and all those
/// inherited conversion functions that are visible in this class.
///
/// Each of the entries in this overload set is a CXXConversionDecl or a
/// FunctionTemplateDecl.
LazyASTUnresolvedSet VisibleConversions;
- /// \brief The declaration which defines this record.
+ /// The declaration which defines this record.
CXXRecordDecl *Definition;
- /// \brief The first friend declaration in this class, or null if there
+ /// The first friend declaration in this class, or null if there
/// aren't any.
///
/// This is actually currently stored in reverse order.
@@ -554,14 +571,14 @@ class CXXRecordDecl : public RecordDecl {
DefinitionData(CXXRecordDecl *D);
- /// \brief Retrieve the set of direct base classes.
+ /// Retrieve the set of direct base classes.
CXXBaseSpecifier *getBases() const {
if (!Bases.isOffset())
return Bases.get(nullptr);
return getBasesSlowCase();
}
- /// \brief Retrieve the set of virtual base classes.
+ /// Retrieve the set of virtual base classes.
CXXBaseSpecifier *getVBases() const {
if (!VBases.isOffset())
return VBases.get(nullptr);
@@ -583,11 +600,11 @@ class CXXRecordDecl : public RecordDecl {
struct DefinitionData *DefinitionData;
- /// \brief Describes a C++ closure type (generated by a lambda expression).
+ /// Describes a C++ closure type (generated by a lambda expression).
struct LambdaDefinitionData : public DefinitionData {
using Capture = LambdaCapture;
- /// \brief Whether this lambda is known to be dependent, even if its
+ /// Whether this lambda is known to be dependent, even if its
/// context isn't dependent.
///
/// A lambda with a non-dependent context can be dependent if it occurs
@@ -597,33 +614,33 @@ class CXXRecordDecl : public RecordDecl {
/// artifact of having to parse the default arguments before.
unsigned Dependent : 1;
- /// \brief Whether this lambda is a generic lambda.
+ /// Whether this lambda is a generic lambda.
unsigned IsGenericLambda : 1;
- /// \brief The Default Capture.
+ /// The Default Capture.
unsigned CaptureDefault : 2;
- /// \brief The number of captures in this lambda is limited 2^NumCaptures.
+ /// The number of captures in this lambda is limited 2^NumCaptures.
unsigned NumCaptures : 15;
- /// \brief The number of explicit captures in this lambda.
+ /// The number of explicit captures in this lambda.
unsigned NumExplicitCaptures : 13;
- /// \brief The number used to indicate this lambda expression for name
+ /// The number used to indicate this lambda expression for name
/// mangling in the Itanium C++ ABI.
unsigned ManglingNumber = 0;
- /// \brief The declaration that provides context for this lambda, if the
+ /// The declaration that provides context for this lambda, if the
/// actual DeclContext does not suffice. This is used for lambdas that
/// occur within default arguments of function parameters within the class
/// or within a data member initializer.
LazyDeclPtr ContextDecl;
- /// \brief The list of captures, both explicit and implicit, for this
+ /// The list of captures, both explicit and implicit, for this
/// lambda.
Capture *Captures = nullptr;
- /// \brief The type of the call method.
+ /// The type of the call method.
TypeSourceInfo *MethodTyInfo;
LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
@@ -661,7 +678,7 @@ class CXXRecordDecl : public RecordDecl {
return static_cast<LambdaDefinitionData&>(*DD);
}
- /// \brief The template or declaration that this declaration
+ /// The template or declaration that this declaration
/// describes or was instantiated from, respectively.
///
/// For non-templates, this value will be null. For record
@@ -673,11 +690,11 @@ class CXXRecordDecl : public RecordDecl {
llvm::PointerUnion<ClassTemplateDecl *, MemberSpecializationInfo *>
TemplateOrInstantiation;
- /// \brief Called from setBases and addedMember to notify the class that a
+ /// Called from setBases and addedMember to notify the class that a
/// direct or virtual base class or a member of class type has been added.
void addedClassSubobject(CXXRecordDecl *Base);
- /// \brief Notify the class that member has been added.
+ /// Notify the class that member has been added.
///
/// This routine helps maintain information about the class based on which
/// members have been added. It will be invoked by DeclContext::addDecl()
@@ -686,20 +703,26 @@ class CXXRecordDecl : public RecordDecl {
void markedVirtualFunctionPure();
- /// \brief Get the head of our list of friend declarations, possibly
+ /// Get the head of our list of friend declarations, possibly
/// deserializing the friends from an external AST source.
FriendDecl *getFirstFriend() const;
+ /// Determine whether this class has an empty base class subobject of type X
+ /// or of one of the types that might be at offset 0 within X (per the C++
+ /// "standard layout" rules).
+ bool hasSubobjectAtOffsetZeroOfEmptyBaseType(ASTContext &Ctx,
+ const CXXRecordDecl *X);
+
protected:
CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
public:
- /// \brief Iterator that traverses the base classes of a class.
+ /// Iterator that traverses the base classes of a class.
using base_class_iterator = CXXBaseSpecifier *;
- /// \brief Iterator that traverses the base classes of a class.
+ /// Iterator that traverses the base classes of a class.
using base_class_const_iterator = const CXXBaseSpecifier *;
CXXRecordDecl *getCanonicalDecl() override {
@@ -728,6 +751,21 @@ public:
return const_cast<CXXRecordDecl*>(this)->getMostRecentDecl();
}
+ CXXRecordDecl *getMostRecentNonInjectedDecl() {
+ CXXRecordDecl *Recent =
+ static_cast<CXXRecordDecl *>(this)->getMostRecentDecl();
+ while (Recent->isInjectedClassName()) {
+ // FIXME: Does injected class name need to be in the redeclarations chain?
+ assert(Recent->getPreviousDecl());
+ Recent = Recent->getPreviousDecl();
+ }
+ return Recent;
+ }
+
+ const CXXRecordDecl *getMostRecentNonInjectedDecl() const {
+ return const_cast<CXXRecordDecl*>(this)->getMostRecentNonInjectedDecl();
+ }
+
CXXRecordDecl *getDefinition() const {
// We only need an update if we don't already know which
// declaration is the definition.
@@ -752,6 +790,18 @@ public:
return data().Polymorphic || data().NumVBases != 0;
}
+ /// @returns true if class is dynamic or might be dynamic because the
+ /// definition is incomplete of dependent.
+ bool mayBeDynamicClass() const {
+ return !hasDefinition() || isDynamicClass() || hasAnyDependentBases();
+ }
+
+ /// @returns true if class is non dynamic or might be non dynamic because the
+ /// definition is incomplete of dependent.
+ bool mayBeNonDynamicClass() const {
+ return !hasDefinition() || !isDynamicClass() || hasAnyDependentBases();
+ }
+
void setIsParsingBaseSpecifiers() { data().IsParsingBaseSpecifiers = true; }
bool isParsingBaseSpecifiers() const {
@@ -760,10 +810,10 @@ public:
unsigned getODRHash() const;
- /// \brief Sets the base classes of this struct or class.
+ /// 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.
+ /// Retrieves the number of base classes of this class.
unsigned getNumBases() const { return data().NumBases; }
using base_class_range = llvm::iterator_range<base_class_iterator>;
@@ -784,7 +834,7 @@ public:
return bases_begin() + data().NumBases;
}
- /// \brief Retrieves the number of virtual base classes of this class.
+ /// Retrieves the number of virtual base classes of this class.
unsigned getNumVBases() const { return data().NumVBases; }
base_class_range vbases() {
@@ -801,7 +851,7 @@ public:
return vbases_begin() + data().NumVBases;
}
- /// \brief Determine whether this class has any dependent base classes which
+ /// Determine whether this class has any dependent base classes which
/// are not the current instantiation.
bool hasAnyDependentBases() const;
@@ -816,13 +866,13 @@ public:
return method_range(method_begin(), method_end());
}
- /// \brief Method begin iterator. Iterates in the order the methods
+ /// Method begin iterator. Iterates in the order the methods
/// were declared.
method_iterator method_begin() const {
return method_iterator(decls_begin());
}
- /// \brief Method past-the-end iterator.
+ /// Method past-the-end iterator.
method_iterator method_end() const {
return method_iterator(decls_end());
}
@@ -857,7 +907,7 @@ public:
return data().FirstFriend.isValid();
}
- /// \brief \c true if a defaulted copy constructor for this class would be
+ /// \c true if a defaulted copy constructor for this class would be
/// deleted.
bool defaultedCopyConstructorIsDeleted() const {
assert((!needsOverloadResolutionForCopyConstructor() ||
@@ -866,7 +916,7 @@ public:
return data().DefaultedCopyConstructorIsDeleted;
}
- /// \brief \c true if a defaulted move constructor for this class would be
+ /// \c true if a defaulted move constructor for this class would be
/// deleted.
bool defaultedMoveConstructorIsDeleted() const {
assert((!needsOverloadResolutionForMoveConstructor() ||
@@ -875,7 +925,7 @@ public:
return data().DefaultedMoveConstructorIsDeleted;
}
- /// \brief \c true if a defaulted destructor for this class would be deleted.
+ /// \c true if a defaulted destructor for this class would be deleted.
bool defaultedDestructorIsDeleted() const {
assert((!needsOverloadResolutionForDestructor() ||
(data().DeclaredSpecialMembers & SMF_Destructor)) &&
@@ -883,41 +933,41 @@ public:
return data().DefaultedDestructorIsDeleted;
}
- /// \brief \c true if we know for sure that this class has a single,
+ /// \c true if we know for sure that this class has a single,
/// accessible, unambiguous copy constructor that is not deleted.
bool hasSimpleCopyConstructor() const {
return !hasUserDeclaredCopyConstructor() &&
!data().DefaultedCopyConstructorIsDeleted;
}
- /// \brief \c true if we know for sure that this class has a single,
+ /// \c true if we know for sure that this class has a single,
/// accessible, unambiguous move constructor that is not deleted.
bool hasSimpleMoveConstructor() const {
return !hasUserDeclaredMoveConstructor() && hasMoveConstructor() &&
!data().DefaultedMoveConstructorIsDeleted;
}
- /// \brief \c true if we know for sure that this class has a single,
+ /// \c true if we know for sure that this class has a single,
/// accessible, unambiguous move assignment operator that is not deleted.
bool hasSimpleMoveAssignment() const {
return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() &&
!data().DefaultedMoveAssignmentIsDeleted;
}
- /// \brief \c true if we know for sure that this class has an accessible
+ /// \c true if we know for sure that this class has an accessible
/// destructor that is not deleted.
bool hasSimpleDestructor() const {
return !hasUserDeclaredDestructor() &&
!data().DefaultedDestructorIsDeleted;
}
- /// \brief Determine whether this class has any default constructors.
+ /// Determine whether this class has any default constructors.
bool hasDefaultConstructor() const {
return (data().DeclaredSpecialMembers & SMF_DefaultConstructor) ||
needsImplicitDefaultConstructor();
}
- /// \brief Determine if we need to declare a default constructor for
+ /// Determine if we need to declare a default constructor for
/// this class.
///
/// This value is used for lazy creation of default constructors.
@@ -930,33 +980,33 @@ public:
!isLambda();
}
- /// \brief Determine whether this class has any user-declared constructors.
+ /// Determine whether this class has any user-declared constructors.
///
/// When true, a default constructor will not be implicitly declared.
bool hasUserDeclaredConstructor() const {
return data().UserDeclaredConstructor;
}
- /// \brief Whether this class has a user-provided default constructor
+ /// Whether this class has a user-provided default constructor
/// per C++11.
bool hasUserProvidedDefaultConstructor() const {
return data().UserProvidedDefaultConstructor;
}
- /// \brief Determine whether this class has a user-declared copy constructor.
+ /// Determine whether this class has a user-declared copy constructor.
///
/// When false, a copy constructor will be implicitly declared.
bool hasUserDeclaredCopyConstructor() const {
return data().UserDeclaredSpecialMembers & SMF_CopyConstructor;
}
- /// \brief Determine whether this class needs an implicit copy
+ /// Determine whether this class needs an implicit copy
/// constructor to be lazily declared.
bool needsImplicitCopyConstructor() const {
return !(data().DeclaredSpecialMembers & SMF_CopyConstructor);
}
- /// \brief Determine whether we need to eagerly declare a defaulted copy
+ /// Determine whether we need to eagerly declare a defaulted copy
/// constructor for this class.
bool needsOverloadResolutionForCopyConstructor() const {
// C++17 [class.copy.ctor]p6:
@@ -971,7 +1021,7 @@ public:
return data().NeedOverloadResolutionForCopyConstructor;
}
- /// \brief Determine whether an implicit copy constructor for this type
+ /// Determine whether an implicit copy constructor for this type
/// would have a parameter with a const-qualified reference type.
bool implicitCopyConstructorHasConstParam() const {
return data().ImplicitCopyConstructorCanHaveConstParamForNonVBase &&
@@ -979,7 +1029,7 @@ public:
data().ImplicitCopyConstructorCanHaveConstParamForVBase);
}
- /// \brief Determine whether this class has a copy constructor with
+ /// Determine whether this class has a copy constructor with
/// a parameter type which is a reference to a const-qualified type.
bool hasCopyConstructorWithConstParam() const {
return data().HasDeclaredCopyConstructorWithConstParam ||
@@ -987,7 +1037,7 @@ public:
implicitCopyConstructorHasConstParam());
}
- /// \brief Whether this class has a user-declared move constructor or
+ /// Whether this class has a user-declared move constructor or
/// assignment operator.
///
/// When false, a move constructor and assignment operator may be
@@ -997,19 +1047,19 @@ public:
(SMF_MoveConstructor | SMF_MoveAssignment);
}
- /// \brief Determine whether this class has had a move constructor
+ /// Determine whether this class has had a move constructor
/// declared by the user.
bool hasUserDeclaredMoveConstructor() const {
return data().UserDeclaredSpecialMembers & SMF_MoveConstructor;
}
- /// \brief Determine whether this class has a move constructor.
+ /// Determine whether this class has a move constructor.
bool hasMoveConstructor() const {
return (data().DeclaredSpecialMembers & SMF_MoveConstructor) ||
needsImplicitMoveConstructor();
}
- /// \brief Set that we attempted to declare an implicit copy
+ /// Set that we attempted to declare an implicit copy
/// constructor, but overload resolution failed so we deleted it.
void setImplicitCopyConstructorIsDeleted() {
assert((data().DefaultedCopyConstructorIsDeleted ||
@@ -1018,7 +1068,7 @@ public:
data().DefaultedCopyConstructorIsDeleted = true;
}
- /// \brief Set that we attempted to declare an implicit move
+ /// Set that we attempted to declare an implicit move
/// constructor, but overload resolution failed so we deleted it.
void setImplicitMoveConstructorIsDeleted() {
assert((data().DefaultedMoveConstructorIsDeleted ||
@@ -1027,7 +1077,7 @@ public:
data().DefaultedMoveConstructorIsDeleted = true;
}
- /// \brief Set that we attempted to declare an implicit destructor,
+ /// Set that we attempted to declare an implicit destructor,
/// but overload resolution failed so we deleted it.
void setImplicitDestructorIsDeleted() {
assert((data().DefaultedDestructorIsDeleted ||
@@ -1036,7 +1086,7 @@ public:
data().DefaultedDestructorIsDeleted = true;
}
- /// \brief Determine whether this class should get an implicit move
+ /// Determine whether this class should get an implicit move
/// constructor or if any existing special member function inhibits this.
bool needsImplicitMoveConstructor() const {
return !(data().DeclaredSpecialMembers & SMF_MoveConstructor) &&
@@ -1046,39 +1096,39 @@ public:
!hasUserDeclaredDestructor();
}
- /// \brief Determine whether we need to eagerly declare a defaulted move
+ /// Determine whether we need to eagerly declare a defaulted move
/// constructor for this class.
bool needsOverloadResolutionForMoveConstructor() const {
return data().NeedOverloadResolutionForMoveConstructor;
}
- /// \brief Determine whether this class has a user-declared copy assignment
+ /// Determine whether this class has a user-declared copy assignment
/// operator.
///
- /// When false, a copy assigment operator will be implicitly declared.
+ /// When false, a copy assignment operator will be implicitly declared.
bool hasUserDeclaredCopyAssignment() const {
return data().UserDeclaredSpecialMembers & SMF_CopyAssignment;
}
- /// \brief Determine whether this class needs an implicit copy
+ /// Determine whether this class needs an implicit copy
/// assignment operator to be lazily declared.
bool needsImplicitCopyAssignment() const {
return !(data().DeclaredSpecialMembers & SMF_CopyAssignment);
}
- /// \brief Determine whether we need to eagerly declare a defaulted copy
+ /// Determine whether we need to eagerly declare a defaulted copy
/// assignment operator for this class.
bool needsOverloadResolutionForCopyAssignment() const {
return data().HasMutableFields;
}
- /// \brief Determine whether an implicit copy assignment operator for this
+ /// Determine whether an implicit copy assignment operator for this
/// type would have a parameter with a const-qualified reference type.
bool implicitCopyAssignmentHasConstParam() const {
return data().ImplicitCopyAssignmentHasConstParam;
}
- /// \brief Determine whether this class has a copy assignment operator with
+ /// Determine whether this class has a copy assignment operator with
/// a parameter type which is a reference to a const-qualified type or is not
/// a reference.
bool hasCopyAssignmentWithConstParam() const {
@@ -1087,19 +1137,19 @@ public:
implicitCopyAssignmentHasConstParam());
}
- /// \brief Determine whether this class has had a move assignment
+ /// Determine whether this class has had a move assignment
/// declared by the user.
bool hasUserDeclaredMoveAssignment() const {
return data().UserDeclaredSpecialMembers & SMF_MoveAssignment;
}
- /// \brief Determine whether this class has a move assignment operator.
+ /// Determine whether this class has a move assignment operator.
bool hasMoveAssignment() const {
return (data().DeclaredSpecialMembers & SMF_MoveAssignment) ||
needsImplicitMoveAssignment();
}
- /// \brief Set that we attempted to declare an implicit move assignment
+ /// Set that we attempted to declare an implicit move assignment
/// operator, but overload resolution failed so we deleted it.
void setImplicitMoveAssignmentIsDeleted() {
assert((data().DefaultedMoveAssignmentIsDeleted ||
@@ -1108,7 +1158,7 @@ public:
data().DefaultedMoveAssignmentIsDeleted = true;
}
- /// \brief Determine whether this class should get an implicit move
+ /// Determine whether this class should get an implicit move
/// assignment operator or if any existing special member function inhibits
/// this.
bool needsImplicitMoveAssignment() const {
@@ -1123,53 +1173,53 @@ public:
!isLambda();
}
- /// \brief Determine whether we need to eagerly declare a move assignment
+ /// Determine whether we need to eagerly declare a move assignment
/// operator for this class.
bool needsOverloadResolutionForMoveAssignment() const {
return data().NeedOverloadResolutionForMoveAssignment;
}
- /// \brief Determine whether this class has a user-declared destructor.
+ /// Determine whether this class has a user-declared destructor.
///
/// When false, a destructor will be implicitly declared.
bool hasUserDeclaredDestructor() const {
return data().UserDeclaredSpecialMembers & SMF_Destructor;
}
- /// \brief Determine whether this class needs an implicit destructor to
+ /// Determine whether this class needs an implicit destructor to
/// be lazily declared.
bool needsImplicitDestructor() const {
return !(data().DeclaredSpecialMembers & SMF_Destructor);
}
- /// \brief Determine whether we need to eagerly declare a destructor for this
+ /// Determine whether we need to eagerly declare a destructor for this
/// class.
bool needsOverloadResolutionForDestructor() const {
return data().NeedOverloadResolutionForDestructor;
}
- /// \brief Determine whether this class describes a lambda function object.
+ /// Determine whether this class describes a lambda function object.
bool isLambda() const {
// An update record can't turn a non-lambda into a lambda.
auto *DD = DefinitionData;
return DD && DD->IsLambda;
}
- /// \brief Determine whether this class describes a generic
+ /// Determine whether this class describes a generic
/// lambda function object (i.e. function call operator is
/// a template).
bool isGenericLambda() const;
- /// \brief Retrieve the lambda call operator of the closure type
+ /// Retrieve the lambda call operator of the closure type
/// if this is a closure type.
CXXMethodDecl *getLambdaCallOperator() const;
- /// \brief Retrieve the lambda static invoker, the address of which
+ /// Retrieve the lambda static invoker, the address of which
/// is returned by the conversion operator, and the body of which
/// is forwarded to the lambda call operator.
CXXMethodDecl *getLambdaStaticInvoker() const;
- /// \brief Retrieve the generic lambda's template parameter list.
+ /// Retrieve the generic lambda's template parameter list.
/// Returns null if the class does not represent a lambda or a generic
/// lambda.
TemplateParameterList *getGenericLambdaTemplateParameterList() const;
@@ -1179,7 +1229,7 @@ public:
return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault);
}
- /// \brief For a closure type, retrieve the mapping from captured
+ /// For a closure type, retrieve the mapping from captured
/// variables and \c this to the non-static data members that store the
/// values or references of the captures.
///
@@ -1225,7 +1275,7 @@ public:
/// this class must currently be in the process of being defined.
void removeConversion(const NamedDecl *Old);
- /// \brief Get all conversion functions visible in current class,
+ /// Get all conversion functions visible in current class,
/// including conversion function templates.
llvm::iterator_range<conversion_iterator> getVisibleConversionFunctions();
@@ -1235,12 +1285,12 @@ public:
/// functions (C++ [dcl.init.aggr]p1).
bool isAggregate() const { return data().Aggregate; }
- /// \brief Whether this class has any in-class initializers
+ /// Whether this class has any in-class initializers
/// 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
+ /// Whether this class or any of its subobjects has any members of
/// reference type which would make value-initialization ill-formed.
///
/// Per C++03 [dcl.init]p5:
@@ -1253,7 +1303,7 @@ public:
data().HasUninitializedReferenceMember;
}
- /// \brief Whether this class is a POD-type (C++ [class]p4)
+ /// Whether this class is a POD-type (C++ [class]p4)
///
/// For purposes of this function a class is POD if it is an aggregate
/// that has no non-static non-POD data members, no reference data
@@ -1263,11 +1313,11 @@ public:
/// Note that this is the C++ TR1 definition of POD.
bool isPOD() const { return data().PlainOldData; }
- /// \brief True if this class is C-like, without C++-specific features, e.g.
+ /// True if this class is C-like, without C++-specific features, e.g.
/// it contains only public fields, no bases, tag kind is not 'class', etc.
bool isCLike() const;
- /// \brief Determine whether this is an empty class in the sense of
+ /// Determine whether this is an empty class in the sense of
/// (C++11 [meta.unary.prop]).
///
/// The CXXRecordDecl is a class type, but not a union type,
@@ -1278,7 +1328,7 @@ public:
/// \note This does NOT include a check for union-ness.
bool isEmpty() const { return data().Empty; }
- /// \brief Determine whether this class has direct non-static data members.
+ /// Determine whether this class has direct non-static data members.
bool hasDirectFields() const {
auto &D = data();
return D.HasPublicFields || D.HasProtectedFields || D.HasPrivateFields;
@@ -1288,32 +1338,36 @@ public:
/// which means that the class contains or inherits a virtual function.
bool isPolymorphic() const { return data().Polymorphic; }
- /// \brief Determine whether this class has a pure virtual function.
+ /// Determine whether this class has a pure virtual function.
///
/// The class is is abstract per (C++ [class.abstract]p2) if it declares
/// a pure virtual function or inherits a pure virtual function that is
/// not overridden.
bool isAbstract() const { return data().Abstract; }
- /// \brief Determine whether this class has standard layout per
- /// (C++ [class]p7)
+ /// Determine whether this class is standard-layout per
+ /// C++ [class]p7.
bool isStandardLayout() const { return data().IsStandardLayout; }
- /// \brief Determine whether this class, or any of its class subobjects,
+ /// Determine whether this class was standard-layout per
+ /// C++11 [class]p7, specifically using the C++11 rules without any DRs.
+ bool isCXX11StandardLayout() const { return data().IsCXX11StandardLayout; }
+
+ /// Determine whether this class, or any of its class subobjects,
/// contains a mutable field.
bool hasMutableFields() const { return data().HasMutableFields; }
- /// \brief Determine whether this class has any variant members.
+ /// Determine whether this class has any variant members.
bool hasVariantMembers() const { return data().HasVariantMembers; }
- /// \brief Determine whether this class has a trivial default constructor
+ /// Determine whether this class has a trivial default constructor
/// (C++11 [class.ctor]p5).
bool hasTrivialDefaultConstructor() const {
return hasDefaultConstructor() &&
(data().HasTrivialSpecialMembers & SMF_DefaultConstructor);
}
- /// \brief Determine whether this class has a non-trivial default constructor
+ /// Determine whether this class has a non-trivial default constructor
/// (C++11 [class.ctor]p5).
bool hasNonTrivialDefaultConstructor() const {
return (data().DeclaredNonTrivialSpecialMembers & SMF_DefaultConstructor) ||
@@ -1321,7 +1375,7 @@ public:
!(data().HasTrivialSpecialMembers & SMF_DefaultConstructor));
}
- /// \brief Determine whether this class has at least one constexpr constructor
+ /// Determine whether this class has at least one constexpr constructor
/// other than the copy or move constructors.
bool hasConstexprNonCopyMoveConstructor() const {
return data().HasConstexprNonCopyMoveConstructor ||
@@ -1329,41 +1383,56 @@ public:
defaultedDefaultConstructorIsConstexpr());
}
- /// \brief Determine whether a defaulted default constructor for this class
+ /// Determine whether a defaulted default constructor for this class
/// would be constexpr.
bool defaultedDefaultConstructorIsConstexpr() const {
return data().DefaultedDefaultConstructorIsConstexpr &&
(!isUnion() || hasInClassInitializer() || !hasVariantMembers());
}
- /// \brief Determine whether this class has a constexpr default constructor.
+ /// Determine whether this class has a constexpr default constructor.
bool hasConstexprDefaultConstructor() const {
return data().HasConstexprDefaultConstructor ||
(needsImplicitDefaultConstructor() &&
defaultedDefaultConstructorIsConstexpr());
}
- /// \brief Determine whether this class has a trivial copy constructor
+ /// Determine whether this class has a trivial copy constructor
/// (C++ [class.copy]p6, C++11 [class.copy]p12)
bool hasTrivialCopyConstructor() const {
return data().HasTrivialSpecialMembers & SMF_CopyConstructor;
}
- /// \brief Determine whether this class has a non-trivial copy constructor
+ bool hasTrivialCopyConstructorForCall() const {
+ return data().HasTrivialSpecialMembersForCall & SMF_CopyConstructor;
+ }
+
+ /// Determine whether this class has a non-trivial copy constructor
/// (C++ [class.copy]p6, C++11 [class.copy]p12)
bool hasNonTrivialCopyConstructor() const {
return data().DeclaredNonTrivialSpecialMembers & SMF_CopyConstructor ||
!hasTrivialCopyConstructor();
}
- /// \brief Determine whether this class has a trivial move constructor
+ bool hasNonTrivialCopyConstructorForCall() const {
+ return (data().DeclaredNonTrivialSpecialMembersForCall &
+ SMF_CopyConstructor) ||
+ !hasTrivialCopyConstructorForCall();
+ }
+
+ /// Determine whether this class has a trivial move constructor
/// (C++11 [class.copy]p12)
bool hasTrivialMoveConstructor() const {
return hasMoveConstructor() &&
(data().HasTrivialSpecialMembers & SMF_MoveConstructor);
}
- /// \brief Determine whether this class has a non-trivial move constructor
+ bool hasTrivialMoveConstructorForCall() const {
+ return hasMoveConstructor() &&
+ (data().HasTrivialSpecialMembersForCall & SMF_MoveConstructor);
+ }
+
+ /// Determine whether this class has a non-trivial move constructor
/// (C++11 [class.copy]p12)
bool hasNonTrivialMoveConstructor() const {
return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveConstructor) ||
@@ -1371,27 +1440,34 @@ public:
!(data().HasTrivialSpecialMembers & SMF_MoveConstructor));
}
- /// \brief Determine whether this class has a trivial copy assignment operator
+ bool hasNonTrivialMoveConstructorForCall() const {
+ return (data().DeclaredNonTrivialSpecialMembersForCall &
+ SMF_MoveConstructor) ||
+ (needsImplicitMoveConstructor() &&
+ !(data().HasTrivialSpecialMembersForCall & SMF_MoveConstructor));
+ }
+
+ /// Determine whether this class has a trivial copy assignment operator
/// (C++ [class.copy]p11, C++11 [class.copy]p25)
bool hasTrivialCopyAssignment() const {
return data().HasTrivialSpecialMembers & SMF_CopyAssignment;
}
- /// \brief Determine whether this class has a non-trivial copy assignment
+ /// Determine whether this class has a non-trivial copy assignment
/// operator (C++ [class.copy]p11, C++11 [class.copy]p25)
bool hasNonTrivialCopyAssignment() const {
return data().DeclaredNonTrivialSpecialMembers & SMF_CopyAssignment ||
!hasTrivialCopyAssignment();
}
- /// \brief Determine whether this class has a trivial move assignment operator
+ /// Determine whether this class has a trivial move assignment operator
/// (C++11 [class.copy]p25)
bool hasTrivialMoveAssignment() const {
return hasMoveAssignment() &&
(data().HasTrivialSpecialMembers & SMF_MoveAssignment);
}
- /// \brief Determine whether this class has a non-trivial move assignment
+ /// Determine whether this class has a non-trivial move assignment
/// operator (C++11 [class.copy]p25)
bool hasNonTrivialMoveAssignment() const {
return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveAssignment) ||
@@ -1399,19 +1475,32 @@ public:
!(data().HasTrivialSpecialMembers & SMF_MoveAssignment));
}
- /// \brief Determine whether this class has a trivial destructor
+ /// Determine whether this class has a trivial destructor
/// (C++ [class.dtor]p3)
bool hasTrivialDestructor() const {
return data().HasTrivialSpecialMembers & SMF_Destructor;
}
- /// \brief Determine whether this class has a non-trivial destructor
+ bool hasTrivialDestructorForCall() const {
+ return data().HasTrivialSpecialMembersForCall & SMF_Destructor;
+ }
+
+ /// Determine whether this class has a non-trivial destructor
/// (C++ [class.dtor]p3)
bool hasNonTrivialDestructor() const {
return !(data().HasTrivialSpecialMembers & SMF_Destructor);
}
- /// \brief Determine whether declaring a const variable with this type is ok
+ bool hasNonTrivialDestructorForCall() const {
+ return !(data().HasTrivialSpecialMembersForCall & SMF_Destructor);
+ }
+
+ void setHasTrivialSpecialMemberForCall() {
+ data().HasTrivialSpecialMembersForCall =
+ (SMF_CopyConstructor | SMF_MoveConstructor | SMF_Destructor);
+ }
+
+ /// Determine whether declaring a const variable with this type is ok
/// per core issue 253.
bool allowConstDefaultInit() const {
return !data().HasUninitializedFields ||
@@ -1419,7 +1508,7 @@ public:
needsImplicitDefaultConstructor());
}
- /// \brief Determine whether this class has a destructor which has no
+ /// Determine whether this class has a destructor which has no
/// semantic effect.
///
/// Any such destructor will be trivial, public, defaulted and not deleted,
@@ -1428,41 +1517,29 @@ public:
return data().HasIrrelevantDestructor;
}
- /// \brief Determine whether this class has at least one trivial, non-deleted
- /// copy or move constructor.
- bool canPassInRegisters() const {
- return data().CanPassInRegisters;
- }
-
- /// \brief Set that we can pass this RecordDecl in registers.
- // FIXME: This should be set as part of completeDefinition.
- void setCanPassInRegisters(bool CanPass) {
- data().CanPassInRegisters = CanPass;
- }
-
- /// \brief Determine whether this class has a non-literal or/ volatile type
+ /// Determine whether this class has a non-literal or/ volatile type
/// non-static data member or base class.
bool hasNonLiteralTypeFieldsOrBases() const {
return data().HasNonLiteralTypeFieldsOrBases;
}
- /// \brief Determine whether this class has a using-declaration that names
+ /// Determine whether this class has a using-declaration that names
/// a user-declared base class constructor.
bool hasInheritedConstructor() const {
return data().HasInheritedConstructor;
}
- /// \brief Determine whether this class has a using-declaration that names
+ /// Determine whether this class has a using-declaration that names
/// a base class assignment operator.
bool hasInheritedAssignment() const {
return data().HasInheritedAssignment;
}
- /// \brief Determine whether this class is considered trivially copyable per
+ /// Determine whether this class is considered trivially copyable per
/// (C++11 [class]p6).
bool isTriviallyCopyable() const;
- /// \brief Determine whether this class is considered trivial.
+ /// Determine whether this class is considered trivial.
///
/// C++11 [class]p6:
/// "A trivial class is a class that has a trivial default constructor and
@@ -1471,7 +1548,7 @@ public:
return isTriviallyCopyable() && hasTrivialDefaultConstructor();
}
- /// \brief Determine whether this class is a literal type.
+ /// Determine whether this class is a literal type.
///
/// C++11 [basic.types]p10:
/// A class type that has all the following properties:
@@ -1497,7 +1574,7 @@ public:
hasTrivialDefaultConstructor());
}
- /// \brief If this record is an instantiation of a member class,
+ /// If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
///
/// This routine will return non-null for (non-templated) member
@@ -1518,17 +1595,17 @@ public:
/// declaration returned by getInstantiatedFromMemberClass().
CXXRecordDecl *getInstantiatedFromMemberClass() const;
- /// \brief If this class is an instantiation of a member class of a
+ /// If this class is an instantiation of a member class of a
/// class template specialization, retrieves the member specialization
/// information.
MemberSpecializationInfo *getMemberSpecializationInfo() const;
- /// \brief Specify that this record is an instantiation of the
+ /// Specify that this record is an instantiation of the
/// member class \p RD.
void setInstantiationOfMemberClass(CXXRecordDecl *RD,
TemplateSpecializationKind TSK);
- /// \brief Retrieves the class template that is described by this
+ /// Retrieves the class template that is described by this
/// class declaration.
///
/// Every class template is represented as a ClassTemplateDecl and a
@@ -1543,15 +1620,15 @@ public:
void setDescribedClassTemplate(ClassTemplateDecl *Template);
- /// \brief Determine whether this particular class is a specialization or
+ /// Determine whether this particular class is a specialization or
/// instantiation of a class template or member class of a class template,
/// and how it was instantiated or specialized.
TemplateSpecializationKind getTemplateSpecializationKind() const;
- /// \brief Set the kind of specialization or template instantiation this is.
+ /// Set the kind of specialization or template instantiation this is.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
- /// \brief Retrieve the record declaration from which this record could be
+ /// Retrieve the record declaration from which this record could be
/// instantiated. Returns null if this class is not a template instantiation.
const CXXRecordDecl *getTemplateInstantiationPattern() const;
@@ -1560,17 +1637,17 @@ public:
->getTemplateInstantiationPattern());
}
- /// \brief Returns the destructor decl for this class.
+ /// Returns the destructor decl for this class.
CXXDestructorDecl *getDestructor() const;
- /// \brief Returns true if the class destructor, or any implicitly invoked
+ /// Returns true if the class destructor, or any implicitly invoked
/// destructors are marked noreturn.
bool isAnyDestructorNoReturn() const;
- /// \brief If the class is a local class [class.local], returns
+ /// If the class is a local class [class.local], returns
/// the enclosing function declaration.
const FunctionDecl *isLocalClass() const {
- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(getDeclContext()))
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(getDeclContext()))
return RD->isLocalClass();
return dyn_cast<FunctionDecl>(getDeclContext());
@@ -1581,11 +1658,11 @@ public:
const_cast<const CXXRecordDecl*>(this)->isLocalClass());
}
- /// \brief Determine whether this dependent class is a current instantiation,
+ /// Determine whether this dependent class is a current instantiation,
/// when viewed from within the given context.
bool isCurrentInstantiation(const DeclContext *CurContext) const;
- /// \brief Determine whether this class is derived from the class \p Base.
+ /// Determine whether this class is derived from the class \p Base.
///
/// This routine only determines whether this class is derived from \p Base,
/// but does not account for factors that may make a Derived -> Base class
@@ -1597,7 +1674,7 @@ public:
/// \returns true if this class is derived from Base, false otherwise.
bool isDerivedFrom(const CXXRecordDecl *Base) const;
- /// \brief Determine whether this class is derived from the type \p Base.
+ /// Determine whether this class is derived from the type \p Base.
///
/// This routine only determines whether this class is derived from \p Base,
/// but does not account for factors that may make a Derived -> Base class
@@ -1615,7 +1692,7 @@ public:
/// tangling input and output in \p Paths
bool isDerivedFrom(const CXXRecordDecl *Base, CXXBasePaths &Paths) const;
- /// \brief Determine whether this class is virtually derived from
+ /// Determine whether this class is virtually derived from
/// the class \p Base.
///
/// This routine only determines whether this class is virtually
@@ -1630,11 +1707,11 @@ public:
/// false otherwise.
bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const;
- /// \brief Determine whether this class is provably not derived from
+ /// Determine whether this class is provably not derived from
/// the type \p Base.
bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const;
- /// \brief Function type used by forallBases() as a callback.
+ /// Function type used by forallBases() as a callback.
///
/// \param BaseDefinition the definition of the base class
///
@@ -1642,7 +1719,7 @@ public:
using ForallBasesCallback =
llvm::function_ref<bool(const CXXRecordDecl *BaseDefinition)>;
- /// \brief Determines if the given callback holds for all the direct
+ /// Determines if the given callback holds for all the direct
/// or indirect base classes of this type.
///
/// The class itself does not count as a base class. This routine
@@ -1658,7 +1735,7 @@ public:
bool forallBases(ForallBasesCallback BaseMatches,
bool AllowShortCircuit = true) const;
- /// \brief Function type used by lookupInBases() to determine whether a
+ /// Function type used by lookupInBases() to determine whether a
/// specific base class subobject matches the lookup criteria.
///
/// \param Specifier the base-class specifier that describes the inheritance
@@ -1672,7 +1749,7 @@ public:
llvm::function_ref<bool(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path)>;
- /// \brief Look for entities within the base classes of this C++ class,
+ /// Look for entities within the base classes of this C++ class,
/// transitively searching all base class subobjects.
///
/// This routine uses the callback function \p BaseMatches to find base
@@ -1696,7 +1773,7 @@ public:
bool lookupInBases(BaseMatchesCallback BaseMatches, CXXBasePaths &Paths,
bool LookupInDependent = false) const;
- /// \brief Base-class lookup callback that determines whether the given
+ /// Base-class lookup callback that determines whether the given
/// base class specifier refers to a specific class declaration.
///
/// This callback can be used with \c lookupInBases() to determine whether
@@ -1706,7 +1783,7 @@ public:
static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path, const CXXRecordDecl *BaseRecord);
- /// \brief Base-class lookup callback that determines whether the
+ /// Base-class lookup callback that determines whether the
/// given base class specifier refers to a specific class
/// declaration and describes virtual derivation.
///
@@ -1719,7 +1796,7 @@ public:
CXXBasePath &Path,
const CXXRecordDecl *BaseRecord);
- /// \brief Base-class lookup callback that determines whether there exists
+ /// Base-class lookup callback that determines whether there exists
/// a tag with the given name.
///
/// This callback can be used with \c lookupInBases() to find tag members
@@ -1727,7 +1804,7 @@ public:
static bool FindTagMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path, DeclarationName Name);
- /// \brief Base-class lookup callback that determines whether there exists
+ /// Base-class lookup callback that determines whether there exists
/// a member with the given name.
///
/// This callback can be used with \c lookupInBases() to find members
@@ -1735,7 +1812,7 @@ public:
static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path, DeclarationName Name);
- /// \brief Base-class lookup callback that determines whether there exists
+ /// Base-class lookup callback that determines whether there exists
/// a member with the given name.
///
/// This callback can be used with \c lookupInBases() to find members
@@ -1745,7 +1822,7 @@ public:
FindOrdinaryMemberInDependentClasses(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path, DeclarationName Name);
- /// \brief Base-class lookup callback that determines whether there exists
+ /// Base-class lookup callback that determines whether there exists
/// an OpenMP declare reduction member with the given name.
///
/// This callback can be used with \c lookupInBases() to find members
@@ -1753,7 +1830,7 @@ public:
static bool FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path, DeclarationName Name);
- /// \brief Base-class lookup callback that determines whether there exists
+ /// Base-class lookup callback that determines whether there exists
/// a member with the given name that can be used in a nested-name-specifier.
///
/// This callback can be used with \c lookupInBases() to find members of
@@ -1763,12 +1840,12 @@ public:
CXXBasePath &Path,
DeclarationName Name);
- /// \brief Retrieve the final overriders for each virtual member
+ /// Retrieve the final overriders for each virtual member
/// function in the class hierarchy where this class is the
/// most-derived class in the class hierarchy.
void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const;
- /// \brief Get the indirect primary bases for this class.
+ /// Get the indirect primary bases for this class.
void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const;
/// Performs an imprecise lookup of a dependent name in this class.
@@ -1784,7 +1861,7 @@ public:
/// GraphViz.
void viewInheritance(ASTContext& Context) const;
- /// \brief Calculates the access of a decl that is reached
+ /// Calculates the access of a decl that is reached
/// along a path.
static AccessSpecifier MergeAccess(AccessSpecifier PathAccess,
AccessSpecifier DeclAccess) {
@@ -1793,14 +1870,16 @@ public:
return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
}
- /// \brief Indicates that the declaration of a defaulted or deleted special
+ /// Indicates that the declaration of a defaulted or deleted special
/// member function is now complete.
void finishedDefaultedOrDeletedMember(CXXMethodDecl *MD);
- /// \brief Indicates that the definition of this class is now complete.
+ void setTrivialForCallFlags(CXXMethodDecl *MD);
+
+ /// Indicates that the definition of this class is now complete.
void completeDefinition() override;
- /// \brief Indicates that the definition of this class is now complete,
+ /// Indicates that the definition of this class is now complete,
/// and provides a final overrider map to help determine
///
/// \param FinalOverriders The final overrider map for this class, which can
@@ -1809,7 +1888,7 @@ public:
/// definition.
void completeDefinition(CXXFinalOverriderMap *FinalOverriders);
- /// \brief Determine whether this class may end up being abstract, even though
+ /// Determine whether this class may end up being abstract, even though
/// it is not yet known to be abstract.
///
/// \returns true if this class is not known to be abstract but has any
@@ -1818,7 +1897,7 @@ public:
/// actually abstract.
bool mayBeAbstract() const;
- /// \brief If this is the closure type of a lambda expression, retrieve the
+ /// If this is the closure type of a lambda expression, retrieve the
/// number to be used for name mangling in the Itanium C++ ABI.
///
/// Zero indicates that this closure type has internal linkage, so the
@@ -1829,7 +1908,7 @@ public:
return getLambdaData().ManglingNumber;
}
- /// \brief Retrieve the declaration that provides additional context for a
+ /// Retrieve the declaration that provides additional context for a
/// lambda, when the normal declaration context is not specific enough.
///
/// Certain contexts (default arguments of in-class function parameters and
@@ -1840,17 +1919,17 @@ public:
/// the declaration context suffices.
Decl *getLambdaContextDecl() const;
- /// \brief Set the mangling number and context declaration for a lambda
+ /// Set the mangling number and context declaration for a lambda
/// class.
void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl) {
getLambdaData().ManglingNumber = ManglingNumber;
getLambdaData().ContextDecl = ContextDecl;
}
- /// \brief Returns the inheritance model used for this record.
+ /// Returns the inheritance model used for this record.
MSInheritanceAttr::Spelling getMSInheritanceModel() const;
- /// \brief Calculate what the inheritance model would be for this class.
+ /// 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
@@ -1865,11 +1944,11 @@ public:
(hasDefinition() && isPolymorphic());
}
- /// \brief Controls when vtordisps will be emitted if this record is used as a
+ /// 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
+ /// 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
/// dependent.
///
@@ -1888,8 +1967,8 @@ public:
return getLambdaData().MethodTyInfo;
}
- // \brief Determine whether this type is an Interface Like type for
- // __interface inheritence purposes.
+ // Determine whether this type is an Interface Like type for
+ // __interface inheritance purposes.
bool isInterfaceLike() const;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -1898,7 +1977,7 @@ public:
}
};
-/// \brief Represents a C++ deduction guide declaration.
+/// Represents a C++ deduction guide declaration.
///
/// \code
/// template<typename T> struct A { A(); A(T); };
@@ -1957,7 +2036,7 @@ public:
static bool classofKind(Kind K) { return K == CXXDeductionGuide; }
};
-/// \brief Represents a static or instance method of a struct/union/class.
+/// Represents a static or instance method of a struct/union/class.
///
/// In the terminology of the C++ Standard, these are the (static and
/// non-static) member functions, whether virtual or not.
@@ -2007,8 +2086,7 @@ public:
bool isVolatile() const { return getType()->castAs<FunctionType>()->isVolatile(); }
bool isVirtual() const {
- CXXMethodDecl *CD =
- cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
+ CXXMethodDecl *CD = const_cast<CXXMethodDecl*>(this)->getCanonicalDecl();
// Member function is virtual if it is marked explicitly so, or if it is
// declared in __interface -- then it is automatically pure virtual.
@@ -2031,16 +2109,16 @@ public:
Base, IsAppleKext);
}
- /// \brief Determine whether this is a usual deallocation function
+ /// Determine whether this is a usual deallocation function
/// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded
/// delete or delete[] operator with a particular signature.
bool isUsualDeallocationFunction() const;
- /// \brief Determine whether this is a copy-assignment operator, regardless
+ /// Determine whether this is a copy-assignment operator, regardless
/// of whether it was declared implicitly or explicitly.
bool isCopyAssignmentOperator() const;
- /// \brief Determine whether this is a move assignment operator.
+ /// Determine whether this is a move assignment operator.
bool isMoveAssignmentOperator() const;
CXXMethodDecl *getCanonicalDecl() override {
@@ -2093,7 +2171,7 @@ public:
cast<CXXRecordDecl>(FunctionDecl::getParent()));
}
- /// \brief Returns the type of the \c this pointer.
+ /// Returns the type of the \c this pointer.
///
/// Should only be called for instance (i.e., non-static) methods. Note
/// that for the call operator of a lambda closure type, this returns the
@@ -2105,7 +2183,7 @@ public:
return getType()->getAs<FunctionProtoType>()->getTypeQuals();
}
- /// \brief Retrieve the ref-qualifier associated with this method.
+ /// Retrieve the ref-qualifier associated with this method.
///
/// In the following example, \c f() has an lvalue ref-qualifier, \c g()
/// has an rvalue ref-qualifier, and \c h() has no ref-qualifier.
@@ -2122,7 +2200,7 @@ public:
bool hasInlineBody() const;
- /// \brief Determine whether this is a lambda closure type's static member
+ /// Determine whether this is a lambda closure type's static member
/// function that is used for the result of the lambda's conversion to
/// function pointer (for a lambda with no captures).
///
@@ -2131,7 +2209,7 @@ public:
/// or clone the function call operator.
bool isLambdaStaticInvoker() const;
- /// \brief Find the method in \p RD that corresponds to this one.
+ /// Find the method in \p RD that corresponds to this one.
///
/// Find if \p RD or one of the classes it inherits from override this method.
/// If so, return it. \p RD is assumed to be a subclass of the class defining
@@ -2154,7 +2232,7 @@ public:
}
};
-/// \brief Represents a C++ base or member initializer.
+/// Represents a C++ base or member initializer.
///
/// This is part of a constructor initializer that
/// initializes one non-static member variable or one base class. For
@@ -2170,13 +2248,13 @@ public:
/// };
/// \endcode
class CXXCtorInitializer final {
- /// \brief Either the base class name/delegating constructor type (stored as
+ /// Either the base class name/delegating constructor type (stored as
/// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field
/// (IndirectFieldDecl*) being initialized.
llvm::PointerUnion3<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *>
Initializee;
- /// \brief The source location for the field name or, for a base initializer
+ /// The source location for the field name or, for a base initializer
/// pack expansion, the location of the ellipsis.
///
/// In the case of a delegating
@@ -2184,25 +2262,25 @@ class CXXCtorInitializer final {
/// Initializee points to the CXXConstructorDecl (to allow loop detection).
SourceLocation MemberOrEllipsisLocation;
- /// \brief The argument used to initialize the base or member, which may
+ /// The argument used to initialize the base or member, which may
/// end up constructing an object (when multiple arguments are involved).
Stmt *Init;
- /// \brief Location of the left paren of the ctor-initializer.
+ /// Location of the left paren of the ctor-initializer.
SourceLocation LParenLoc;
- /// \brief Location of the right paren of the ctor-initializer.
+ /// Location of the right paren of the ctor-initializer.
SourceLocation RParenLoc;
- /// \brief If the initializee is a type, whether that type makes this
+ /// If the initializee is a type, whether that type makes this
/// a delegating initialization.
unsigned IsDelegating : 1;
- /// \brief If the initializer is a base initializer, this keeps track
+ /// If the initializer is a base initializer, this keeps track
/// of whether the base is virtual or not.
unsigned IsVirtual : 1;
- /// \brief Whether or not the initializer is explicitly written
+ /// Whether or not the initializer is explicitly written
/// in the sources.
unsigned IsWritten : 1;
@@ -2211,35 +2289,35 @@ class CXXCtorInitializer final {
unsigned SourceOrder : 13;
public:
- /// \brief Creates a new base-class initializer.
+ /// Creates a new base-class initializer.
explicit
CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, bool IsVirtual,
SourceLocation L, Expr *Init, SourceLocation R,
SourceLocation EllipsisLoc);
- /// \brief Creates a new member initializer.
+ /// Creates a new member initializer.
explicit
CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
SourceLocation MemberLoc, SourceLocation L, Expr *Init,
SourceLocation R);
- /// \brief Creates a new anonymous field initializer.
+ /// Creates a new anonymous field initializer.
explicit
CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member,
SourceLocation MemberLoc, SourceLocation L, Expr *Init,
SourceLocation R);
- /// \brief Creates a new delegating initializer.
+ /// Creates a new delegating initializer.
explicit
CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo,
SourceLocation L, Expr *Init, SourceLocation R);
- /// \brief Determine whether this initializer is initializing a base class.
+ /// Determine whether this initializer is initializing a base class.
bool isBaseInitializer() const {
return Initializee.is<TypeSourceInfo*>() && !IsDelegating;
}
- /// \brief Determine whether this initializer is initializing a non-static
+ /// Determine whether this initializer is initializing a non-static
/// data member.
bool isMemberInitializer() const { return Initializee.is<FieldDecl*>(); }
@@ -2251,7 +2329,7 @@ public:
return Initializee.is<IndirectFieldDecl*>();
}
- /// \brief Determine whether this initializer is an implicit initializer
+ /// Determine whether this initializer is an implicit initializer
/// generated for a field with an initializer defined on the member
/// declaration.
///
@@ -2261,18 +2339,18 @@ public:
return Init->getStmtClass() == Stmt::CXXDefaultInitExprClass;
}
- /// \brief Determine whether this initializer is creating a delegating
+ /// Determine whether this initializer is creating a delegating
/// constructor.
bool isDelegatingInitializer() const {
return Initializee.is<TypeSourceInfo*>() && IsDelegating;
}
- /// \brief Determine whether this initializer is a pack expansion.
+ /// Determine whether this initializer is a pack expansion.
bool isPackExpansion() const {
return isBaseInitializer() && MemberOrEllipsisLocation.isValid();
}
- // \brief For a pack expansion, returns the location of the ellipsis.
+ // For a pack expansion, returns the location of the ellipsis.
SourceLocation getEllipsisLoc() const {
assert(isPackExpansion() && "Initializer is not a pack expansion");
return MemberOrEllipsisLocation;
@@ -2294,13 +2372,13 @@ public:
return IsVirtual;
}
- /// \brief Returns the declarator information for a base class or delegating
+ /// Returns the declarator information for a base class or delegating
/// initializer.
TypeSourceInfo *getTypeSourceInfo() const {
return Initializee.dyn_cast<TypeSourceInfo *>();
}
- /// \brief If this is a member initializer, returns the declaration of the
+ /// If this is a member initializer, returns the declaration of the
/// non-static data member being initialized. Otherwise, returns null.
FieldDecl *getMember() const {
if (isMemberInitializer())
@@ -2326,23 +2404,23 @@ public:
return MemberOrEllipsisLocation;
}
- /// \brief Determine the source location of the initializer.
+ /// Determine the source location of the initializer.
SourceLocation getSourceLocation() const;
- /// \brief Determine the source range covering the entire initializer.
+ /// Determine the source range covering the entire initializer.
SourceRange getSourceRange() const LLVM_READONLY;
- /// \brief Determine whether this initializer is explicitly written
+ /// Determine whether this initializer is explicitly written
/// in the source code.
bool isWritten() const { return IsWritten; }
- /// \brief Return the source position of the initializer, counting from 0.
+ /// Return the source position of the initializer, counting from 0.
/// If the initializer was implicit, -1 is returned.
int getSourceOrder() const {
return IsWritten ? static_cast<int>(SourceOrder) : -1;
}
- /// \brief Set the source order of this initializer.
+ /// Set the source order of this initializer.
///
/// This can only be called once for each initializer; it cannot be called
/// on an initializer having a positive number of (implicit) array indices.
@@ -2363,8 +2441,8 @@ public:
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
- /// \brief Get the initializer.
- Expr *getInit() const { return static_cast<Expr*>(Init); }
+ /// Get the initializer.
+ Expr *getInit() const { return static_cast<Expr *>(Init); }
};
/// Description of a constructor that was inherited from a base class.
@@ -2384,7 +2462,7 @@ public:
CXXConstructorDecl *getConstructor() const { return BaseCtor; }
};
-/// \brief Represents a C++ constructor within a class.
+/// Represents a C++ constructor within a class.
///
/// For example:
///
@@ -2399,12 +2477,12 @@ class CXXConstructorDecl final
private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor> {
/// \name Support for base and member initializers.
/// \{
- /// \brief The arguments used to initialize the base or member.
+ /// The arguments used to initialize the base or member.
LazyCXXCtorInitializersPtr CtorInitializers;
unsigned NumCtorInitializers : 31;
/// \}
- /// \brief Whether this constructor declaration is an implicitly-declared
+ /// Whether this constructor declaration is an implicitly-declared
/// inheriting constructor.
unsigned IsInheritingConstructor : 1;
@@ -2439,10 +2517,10 @@ public:
bool isConstexpr,
InheritedConstructor Inherited = InheritedConstructor());
- /// \brief Iterates through the member/base initializer list.
+ /// Iterates through the member/base initializer list.
using init_iterator = CXXCtorInitializer **;
- /// \brief Iterates through the member/base initializer list.
+ /// Iterates through the member/base initializer list.
using init_const_iterator = CXXCtorInitializer *const *;
using init_range = llvm::iterator_range<init_iterator>;
@@ -2453,21 +2531,21 @@ public:
return init_const_range(init_begin(), init_end());
}
- /// \brief Retrieve an iterator to the first initializer.
+ /// Retrieve an iterator to the first initializer.
init_iterator init_begin() {
const auto *ConstThis = this;
return const_cast<init_iterator>(ConstThis->init_begin());
}
- /// \brief Retrieve an iterator to the first initializer.
+ /// Retrieve an iterator to the first initializer.
init_const_iterator init_begin() const;
- /// \brief Retrieve an iterator past the last initializer.
+ /// Retrieve an iterator past the last initializer.
init_iterator init_end() {
return init_begin() + NumCtorInitializers;
}
- /// \brief Retrieve an iterator past the last initializer.
+ /// Retrieve an iterator past the last initializer.
init_const_iterator init_end() const {
return init_begin() + NumCtorInitializers;
}
@@ -2490,7 +2568,7 @@ public:
return init_const_reverse_iterator(init_begin());
}
- /// \brief Determine the number of arguments used to initialize the member
+ /// Determine the number of arguments used to initialize the member
/// or base.
unsigned getNumCtorInitializers() const {
return NumCtorInitializers;
@@ -2512,13 +2590,13 @@ public:
return getCanonicalDecl()->isExplicitSpecified();
}
- /// \brief Determine whether this constructor is a delegating constructor.
+ /// Determine whether this constructor is a delegating constructor.
bool isDelegatingConstructor() const {
return (getNumCtorInitializers() == 1) &&
init_begin()[0]->isDelegatingInitializer();
}
- /// \brief When this constructor delegates to another, retrieve the target.
+ /// When this constructor delegates to another, retrieve the target.
CXXConstructorDecl *getTargetConstructor() const;
/// Whether this constructor is a default
@@ -2526,7 +2604,7 @@ public:
/// default-initialize a class of this type.
bool isDefaultConstructor() const;
- /// \brief Whether this constructor is a copy constructor (C++ [class.copy]p2,
+ /// Whether this constructor is a copy constructor (C++ [class.copy]p2,
/// which can be used to copy the class.
///
/// \p TypeQuals will be set to the qualifiers on the
@@ -2549,27 +2627,27 @@ public:
return isCopyConstructor(TypeQuals);
}
- /// \brief Determine whether this constructor is a move constructor
+ /// Determine whether this constructor is a move constructor
/// (C++11 [class.copy]p3), which can be used to move values of the class.
///
/// \param TypeQuals If this constructor is a move constructor, will be set
/// to the type qualifiers on the referent of the first parameter's type.
bool isMoveConstructor(unsigned &TypeQuals) const;
- /// \brief Determine whether this constructor is a move constructor
+ /// Determine whether this constructor is a move constructor
/// (C++11 [class.copy]p3), which can be used to move values of the class.
bool isMoveConstructor() const {
unsigned TypeQuals = 0;
return isMoveConstructor(TypeQuals);
}
- /// \brief Determine whether this is a copy or move constructor.
+ /// Determine whether this is a copy or move constructor.
///
/// \param TypeQuals Will be set to the type qualifiers on the reference
/// parameter, if in fact this is a copy or move constructor.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const;
- /// \brief Determine whether this a copy or move constructor.
+ /// Determine whether this a copy or move constructor.
bool isCopyOrMoveConstructor() const {
unsigned Quals;
return isCopyOrMoveConstructor(Quals);
@@ -2580,16 +2658,16 @@ public:
/// used for user-defined conversions.
bool isConvertingConstructor(bool AllowExplicit) const;
- /// \brief Determine whether this is a member template specialization that
+ /// Determine whether this is a member template specialization that
/// would copy the object to itself. Such constructors are never used to copy
/// an object.
bool isSpecializationCopyingObject() const;
- /// \brief Determine whether this is an implicit constructor synthesized to
+ /// Determine whether this is an implicit constructor synthesized to
/// model a call to a constructor inherited from a base class.
bool isInheritingConstructor() const { return IsInheritingConstructor; }
- /// \brief Get the constructor that this inheriting constructor is based on.
+ /// Get the constructor that this inheriting constructor is based on.
InheritedConstructor getInheritedConstructor() const {
return IsInheritingConstructor ? *getTrailingObjects<InheritedConstructor>()
: InheritedConstructor();
@@ -2607,7 +2685,7 @@ public:
static bool classofKind(Kind K) { return K == CXXConstructor; }
};
-/// \brief Represents a C++ destructor within a class.
+/// Represents a C++ destructor within a class.
///
/// For example:
///
@@ -2669,7 +2747,7 @@ public:
static bool classofKind(Kind K) { return K == CXXDestructor; }
};
-/// \brief Represents a C++ conversion function within a class.
+/// Represents a C++ conversion function within a class.
///
/// For example:
///
@@ -2713,12 +2791,12 @@ public:
return getCanonicalDecl()->isExplicitSpecified();
}
- /// \brief Returns the type that this conversion function is converting to.
+ /// Returns the type that this conversion function is converting to.
QualType getConversionType() const {
return getType()->getAs<FunctionType>()->getReturnType();
}
- /// \brief Determine whether this conversion function is a conversion from
+ /// Determine whether this conversion function is a conversion from
/// a lambda closure type to a block pointer.
bool isLambdaToBlockPointerConversion() const;
@@ -2734,7 +2812,7 @@ public:
static bool classofKind(Kind K) { return K == CXXConversion; }
};
-/// \brief Represents a linkage specification.
+/// Represents a linkage specification.
///
/// For example:
/// \code
@@ -2744,7 +2822,7 @@ class LinkageSpecDecl : public Decl, public DeclContext {
virtual void anchor();
public:
- /// \brief Represents the language in a linkage specification.
+ /// Represents the language in a linkage specification.
///
/// The values are part of the serialization ABI for
/// ASTs and cannot be changed without altering that ABI. To help
@@ -2756,20 +2834,20 @@ public:
};
private:
- /// \brief The language for this linkage specification.
+ /// The language for this linkage specification.
unsigned Language : 3;
- /// \brief True if this linkage spec has braces.
+ /// True if this linkage spec has braces.
///
/// This is needed so that hasBraces() returns the correct result while the
/// linkage spec body is being parsed. Once RBraceLoc has been set this is
/// not used, so it doesn't need to be serialized.
unsigned HasBraces : 1;
- /// \brief The source location for the extern keyword.
+ /// The source location for the extern keyword.
SourceLocation ExternLoc;
- /// \brief The source location for the right brace (if valid).
+ /// The source location for the right brace (if valid).
SourceLocation RBraceLoc;
LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
@@ -2785,13 +2863,13 @@ public:
bool HasBraces);
static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- /// \brief Return the language specified by this linkage specification.
+ /// Return the language specified by this linkage specification.
LanguageIDs getLanguage() const { return LanguageIDs(Language); }
- /// \brief Set the language specified by this linkage specification.
+ /// Set the language specified by this linkage specification.
void setLanguage(LanguageIDs L) { Language = L; }
- /// \brief Determines whether this linkage specification had braces in
+ /// Determines whether this linkage specification had braces in
/// its syntactic form.
bool hasBraces() const {
assert(!RBraceLoc.isValid() || HasBraces);
@@ -2830,7 +2908,7 @@ public:
}
};
-/// \brief Represents C++ using-directive.
+/// Represents C++ using-directive.
///
/// For example:
/// \code
@@ -2841,16 +2919,16 @@ public:
/// artificial names for all using-directives in order to store
/// them in DeclContext effectively.
class UsingDirectiveDecl : public NamedDecl {
- /// \brief The location of the \c using keyword.
+ /// The location of the \c using keyword.
SourceLocation UsingLoc;
- /// \brief The location of the \c namespace keyword.
+ /// The location of the \c namespace keyword.
SourceLocation NamespaceLoc;
- /// \brief The nested-name-specifier that precedes the namespace.
+ /// The nested-name-specifier that precedes the namespace.
NestedNameSpecifierLoc QualifierLoc;
- /// \brief The namespace nominated by this using-directive.
+ /// The namespace nominated by this using-directive.
NamedDecl *NominatedNamespace;
/// Enclosing context containing both using-directive and nominated
@@ -2867,7 +2945,7 @@ class UsingDirectiveDecl : public NamedDecl {
NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc),
NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) {}
- /// \brief Returns special DeclarationName used by using-directives.
+ /// Returns special DeclarationName used by using-directives.
///
/// This is only used by DeclContext for storing UsingDirectiveDecls in
/// its lookup structure.
@@ -2883,11 +2961,11 @@ public:
// Friend for getUsingDirectiveName.
friend class DeclContext;
- /// \brief Retrieve the nested-name-specifier that qualifies the
+ /// Retrieve the nested-name-specifier that qualifies the
/// name of the namespace, with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// \brief Retrieve the nested-name-specifier that qualifies the
+ /// Retrieve the nested-name-specifier that qualifies the
/// name of the namespace.
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
@@ -2898,26 +2976,26 @@ public:
return NominatedNamespace;
}
- /// \brief Returns the namespace nominated by this using-directive.
+ /// Returns the namespace nominated by this using-directive.
NamespaceDecl *getNominatedNamespace();
const NamespaceDecl *getNominatedNamespace() const {
return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
}
- /// \brief Returns the common ancestor context of this using-directive and
+ /// Returns the common ancestor context of this using-directive and
/// its nominated namespace.
DeclContext *getCommonAncestor() { return CommonAncestor; }
const DeclContext *getCommonAncestor() const { return CommonAncestor; }
- /// \brief Return the location of the \c using keyword.
+ /// Return the location of the \c using keyword.
SourceLocation getUsingLoc() const { return UsingLoc; }
// FIXME: Could omit 'Key' in name.
- /// \brief Returns the location of the \c namespace keyword.
+ /// Returns the location of the \c namespace keyword.
SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
- /// \brief Returns the location of this using declaration's identifier.
+ /// Returns the location of this using declaration's identifier.
SourceLocation getIdentLocation() const { return getLocation(); }
static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2937,7 +3015,7 @@ public:
static bool classofKind(Kind K) { return K == UsingDirective; }
};
-/// \brief Represents a C++ namespace alias.
+/// Represents a C++ namespace alias.
///
/// For example:
///
@@ -2948,18 +3026,18 @@ class NamespaceAliasDecl : public NamedDecl,
public Redeclarable<NamespaceAliasDecl> {
friend class ASTDeclReader;
- /// \brief The location of the \c namespace keyword.
+ /// The location of the \c namespace keyword.
SourceLocation NamespaceLoc;
- /// \brief The location of the namespace's identifier.
+ /// The location of the namespace's identifier.
///
/// This is accessed by TargetNameLoc.
SourceLocation IdentLoc;
- /// \brief The nested-name-specifier that precedes the namespace.
+ /// The nested-name-specifier that precedes the namespace.
NestedNameSpecifierLoc QualifierLoc;
- /// \brief The Decl that this alias points to, either a NamespaceDecl or
+ /// The Decl that this alias points to, either a NamespaceDecl or
/// a NamespaceAliasDecl.
NamedDecl *Namespace;
@@ -3006,26 +3084,26 @@ public:
return getFirstDecl();
}
- /// \brief Retrieve the nested-name-specifier that qualifies the
+ /// Retrieve the nested-name-specifier that qualifies the
/// name of the namespace, with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// \brief Retrieve the nested-name-specifier that qualifies the
+ /// Retrieve the nested-name-specifier that qualifies the
/// name of the namespace.
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
- /// \brief Retrieve the namespace declaration aliased by this directive.
+ /// Retrieve the namespace declaration aliased by this directive.
NamespaceDecl *getNamespace() {
- if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
+ if (auto *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
return AD->getNamespace();
return cast<NamespaceDecl>(Namespace);
}
const NamespaceDecl *getNamespace() const {
- return const_cast<NamespaceAliasDecl*>(this)->getNamespace();
+ return const_cast<NamespaceAliasDecl *>(this)->getNamespace();
}
/// Returns the location of the alias name, i.e. 'foo' in
@@ -3038,7 +3116,7 @@ public:
/// Returns the location of the identifier in the named namespace.
SourceLocation getTargetNameLoc() const { return IdentLoc; }
- /// \brief Retrieve the namespace that this alias refers to, which
+ /// Retrieve the namespace that this alias refers to, which
/// may either be a NamespaceDecl or a NamespaceAliasDecl.
NamedDecl *getAliasedNamespace() const { return Namespace; }
@@ -3050,7 +3128,7 @@ public:
static bool classofKind(Kind K) { return K == NamespaceAlias; }
};
-/// \brief Represents a shadow declaration introduced into a scope by a
+/// Represents a shadow declaration introduced into a scope by a
/// (resolved) using declaration.
///
/// For example,
@@ -3069,7 +3147,7 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
/// The referenced declaration.
NamedDecl *Underlying = nullptr;
- /// \brief The using declaration which introduced this decl or the next using
+ /// The using declaration which introduced this decl or the next using
/// shadow declaration contained in the aforementioned using declaration.
NamedDecl *UsingOrNextShadow = nullptr;
@@ -3123,22 +3201,26 @@ public:
return getFirstDecl();
}
- /// \brief Gets the underlying declaration which has been brought into the
+ /// Gets the underlying declaration which has been brought into the
/// local scope.
NamedDecl *getTargetDecl() const { return Underlying; }
- /// \brief Sets the underlying declaration which has been brought into the
+ /// Sets the underlying declaration which has been brought into the
/// local scope.
- void setTargetDecl(NamedDecl* ND) {
+ void setTargetDecl(NamedDecl *ND) {
assert(ND && "Target decl is null!");
Underlying = ND;
- IdentifierNamespace = ND->getIdentifierNamespace();
+ // A UsingShadowDecl is never a friend or local extern declaration, even
+ // if it is a shadow declaration for one.
+ IdentifierNamespace =
+ ND->getIdentifierNamespace() &
+ ~(IDNS_OrdinaryFriend | IDNS_TagFriend | IDNS_LocalExtern);
}
- /// \brief Gets the using declaration to which this declaration is tied.
+ /// Gets the using declaration to which this declaration is tied.
UsingDecl *getUsingDecl() const;
- /// \brief The next using shadow declaration contained in the shadow decl
+ /// The next using shadow declaration contained in the shadow decl
/// chain of the using declaration which introduced this decl.
UsingShadowDecl *getNextUsingShadowDecl() const {
return dyn_cast_or_null<UsingShadowDecl>(UsingOrNextShadow);
@@ -3150,7 +3232,7 @@ public:
}
};
-/// \brief Represents a shadow constructor declaration introduced into a
+/// Represents a shadow constructor declaration introduced into a
/// class by a C++11 using-declaration that names a constructor.
///
/// For example:
@@ -3161,18 +3243,18 @@ public:
/// };
/// \endcode
class ConstructorUsingShadowDecl final : public UsingShadowDecl {
- /// \brief If this constructor using declaration inherted the constructor
+ /// If this constructor using declaration inherted the constructor
/// from an indirect base class, this is the ConstructorUsingShadowDecl
/// in the named direct base class from which the declaration was inherited.
ConstructorUsingShadowDecl *NominatedBaseClassShadowDecl = nullptr;
- /// \brief If this constructor using declaration inherted the constructor
+ /// If this constructor using declaration inherted the constructor
/// from an indirect base class, this is the ConstructorUsingShadowDecl
/// that will be used to construct the unique direct or virtual base class
/// that receives the constructor arguments.
ConstructorUsingShadowDecl *ConstructedBaseClassShadowDecl = nullptr;
- /// \brief \c true if the constructor ultimately named by this using shadow
+ /// \c true if the constructor ultimately named by this using shadow
/// declaration is within a virtual base class subobject of the class that
/// contains this declaration.
unsigned IsVirtual : 1;
@@ -3224,24 +3306,24 @@ public:
}
//@}
- /// \brief Get the inheriting constructor declaration for the direct base
+ /// Get the inheriting constructor declaration for the direct base
/// class from which this using shadow declaration was inherited, if there is
/// one. This can be different for each redeclaration of the same shadow decl.
ConstructorUsingShadowDecl *getNominatedBaseClassShadowDecl() const {
return NominatedBaseClassShadowDecl;
}
- /// \brief Get the inheriting constructor declaration for the base class
+ /// Get the inheriting constructor declaration for the base class
/// for which we don't have an explicit initializer, if there is one.
ConstructorUsingShadowDecl *getConstructedBaseClassShadowDecl() const {
return ConstructedBaseClassShadowDecl;
}
- /// \brief Get the base class that was named in the using declaration. This
+ /// Get the base class that was named in the using declaration. This
/// can be different for each redeclaration of this same shadow decl.
CXXRecordDecl *getNominatedBaseClass() const;
- /// \brief Get the base class whose constructor or constructor shadow
+ /// Get the base class whose constructor or constructor shadow
/// declaration is passed the constructor arguments.
CXXRecordDecl *getConstructedBaseClass() const {
return cast<CXXRecordDecl>((ConstructedBaseClassShadowDecl
@@ -3250,13 +3332,13 @@ public:
->getDeclContext());
}
- /// \brief Returns \c true if the constructed base class is a virtual base
+ /// Returns \c true if the constructed base class is a virtual base
/// class subobject of this declaration's class.
bool constructsVirtualBase() const {
return IsVirtual;
}
- /// \brief Get the constructor or constructor template in the derived class
+ /// Get the constructor or constructor template in the derived class
/// correspnding to this using shadow declaration, if it has been implicitly
/// declared already.
CXXConstructorDecl *getConstructor() const;
@@ -3266,24 +3348,24 @@ public:
static bool classofKind(Kind K) { return K == ConstructorUsingShadow; }
};
-/// \brief Represents a C++ using-declaration.
+/// Represents a C++ using-declaration.
///
/// For example:
/// \code
/// using someNameSpace::someIdentifier;
/// \endcode
class UsingDecl : public NamedDecl, public Mergeable<UsingDecl> {
- /// \brief The source location of the 'using' keyword itself.
+ /// The source location of the 'using' keyword itself.
SourceLocation UsingLocation;
- /// \brief The nested-name-specifier that precedes the name.
+ /// The nested-name-specifier that precedes the name.
NestedNameSpecifierLoc QualifierLoc;
- /// \brief Provides source/type location info for the declaration name
+ /// Provides source/type location info for the declaration name
/// embedded in the ValueDecl base class.
DeclarationNameLoc DNLoc;
- /// \brief The first shadow declaration of the shadow decl chain associated
+ /// The first shadow declaration of the shadow decl chain associated
/// with this using declaration.
///
/// The bool member of the pair store whether this decl has the \c typename
@@ -3304,17 +3386,17 @@ public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
- /// \brief Return the source location of the 'using' keyword.
+ /// Return the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return UsingLocation; }
- /// \brief Set the source location of the 'using' keyword.
+ /// Set the source location of the 'using' keyword.
void setUsingLoc(SourceLocation L) { UsingLocation = L; }
- /// \brief Retrieve the nested-name-specifier that qualifies the name,
+ /// Retrieve the nested-name-specifier that qualifies the name,
/// with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// \brief Retrieve the nested-name-specifier that qualifies the name.
+ /// Retrieve the nested-name-specifier that qualifies the name.
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
@@ -3323,19 +3405,19 @@ public:
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
- /// \brief Return true if it is a C++03 access declaration (no 'using').
+ /// Return true if it is a C++03 access declaration (no 'using').
bool isAccessDeclaration() const { return UsingLocation.isInvalid(); }
- /// \brief Return true if the using declaration has 'typename'.
+ /// Return true if the using declaration has 'typename'.
bool hasTypename() const { return FirstUsingShadow.getInt(); }
- /// \brief Sets whether the using declaration has 'typename'.
+ /// Sets whether the using declaration has 'typename'.
void setTypename(bool TN) { FirstUsingShadow.setInt(TN); }
- /// \brief Iterates through the using shadow declarations associated with
+ /// Iterates through the using shadow declarations associated with
/// this using declaration.
class shadow_iterator {
- /// \brief The current using shadow declaration.
+ /// The current using shadow declaration.
UsingShadowDecl *Current = nullptr;
public:
@@ -3382,7 +3464,7 @@ public:
shadow_iterator shadow_end() const { return shadow_iterator(); }
- /// \brief Return the number of shadowed declarations associated with this
+ /// Return the number of shadowed declarations associated with this
/// using declaration.
unsigned shadow_size() const {
return std::distance(shadow_begin(), shadow_end());
@@ -3480,7 +3562,7 @@ public:
static bool classofKind(Kind K) { return K == UsingPack; }
};
-/// \brief Represents a dependent using declaration which was not marked with
+/// Represents a dependent using declaration which was not marked with
/// \c typename.
///
/// Unlike non-dependent using declarations, these *only* bring through
@@ -3493,16 +3575,16 @@ public:
/// \endcode
class UnresolvedUsingValueDecl : public ValueDecl,
public Mergeable<UnresolvedUsingValueDecl> {
- /// \brief The source location of the 'using' keyword
+ /// The source location of the 'using' keyword
SourceLocation UsingLocation;
- /// \brief If this is a pack expansion, the location of the '...'.
+ /// If this is a pack expansion, the location of the '...'.
SourceLocation EllipsisLoc;
- /// \brief The nested-name-specifier that precedes the name.
+ /// The nested-name-specifier that precedes the name.
NestedNameSpecifierLoc QualifierLoc;
- /// \brief Provides source/type location info for the declaration name
+ /// Provides source/type location info for the declaration name
/// embedded in the ValueDecl base class.
DeclarationNameLoc DNLoc;
@@ -3522,20 +3604,20 @@ public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
- /// \brief Returns the source location of the 'using' keyword.
+ /// Returns the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return UsingLocation; }
- /// \brief Set the source location of the 'using' keyword.
+ /// Set the source location of the 'using' keyword.
void setUsingLoc(SourceLocation L) { UsingLocation = L; }
- /// \brief Return true if it is a C++03 access declaration (no 'using').
+ /// Return true if it is a C++03 access declaration (no 'using').
bool isAccessDeclaration() const { return UsingLocation.isInvalid(); }
- /// \brief Retrieve the nested-name-specifier that qualifies the name,
+ /// Retrieve the nested-name-specifier that qualifies the name,
/// with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// \brief Retrieve the nested-name-specifier that qualifies the name.
+ /// Retrieve the nested-name-specifier that qualifies the name.
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
@@ -3544,12 +3626,12 @@ public:
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
- /// \brief Determine whether this is a pack expansion.
+ /// Determine whether this is a pack expansion.
bool isPackExpansion() const {
return EllipsisLoc.isValid();
}
- /// \brief Get the location of the ellipsis if this is a pack expansion.
+ /// Get the location of the ellipsis if this is a pack expansion.
SourceLocation getEllipsisLoc() const {
return EllipsisLoc;
}
@@ -3576,7 +3658,7 @@ public:
static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
};
-/// \brief Represents a dependent using declaration which was marked with
+/// Represents a dependent using declaration which was marked with
/// \c typename.
///
/// \code
@@ -3592,13 +3674,13 @@ class UnresolvedUsingTypenameDecl
public Mergeable<UnresolvedUsingTypenameDecl> {
friend class ASTDeclReader;
- /// \brief The source location of the 'typename' keyword
+ /// The source location of the 'typename' keyword
SourceLocation TypenameLocation;
- /// \brief If this is a pack expansion, the location of the '...'.
+ /// If this is a pack expansion, the location of the '...'.
SourceLocation EllipsisLoc;
- /// \brief The nested-name-specifier that precedes the name.
+ /// The nested-name-specifier that precedes the name.
NestedNameSpecifierLoc QualifierLoc;
UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
@@ -3615,17 +3697,17 @@ class UnresolvedUsingTypenameDecl
void anchor() override;
public:
- /// \brief Returns the source location of the 'using' keyword.
+ /// Returns the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return getLocStart(); }
- /// \brief Returns the source location of the 'typename' keyword.
+ /// Returns the source location of the 'typename' keyword.
SourceLocation getTypenameLoc() const { return TypenameLocation; }
- /// \brief Retrieve the nested-name-specifier that qualifies the name,
+ /// Retrieve the nested-name-specifier that qualifies the name,
/// with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// \brief Retrieve the nested-name-specifier that qualifies the name.
+ /// Retrieve the nested-name-specifier that qualifies the name.
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
@@ -3634,12 +3716,12 @@ public:
return DeclarationNameInfo(getDeclName(), getLocation());
}
- /// \brief Determine whether this is a pack expansion.
+ /// Determine whether this is a pack expansion.
bool isPackExpansion() const {
return EllipsisLoc.isValid();
}
- /// \brief Get the location of the ellipsis if this is a pack expansion.
+ /// Get the location of the ellipsis if this is a pack expansion.
SourceLocation getEllipsisLoc() const {
return EllipsisLoc;
}
@@ -3665,7 +3747,7 @@ public:
static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
};
-/// \brief Represents a C++11 static_assert declaration.
+/// Represents a C++11 static_assert declaration.
class StaticAssertDecl : public Decl {
llvm::PointerIntPair<Expr *, 1, bool> AssertExprAndFailed;
StringLiteral *Message;
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index 6545f70f70b55..ccd82d2cf0d21 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -30,17 +30,17 @@ namespace clang {
class DependentDiagnostic;
-/// \brief An array of decls optimized for the common case of only containing
+/// An array of decls optimized for the common case of only containing
/// one entry.
struct StoredDeclsList {
- /// \brief When in vector form, this is what the Data pointer points to.
+ /// When in vector form, this is what the Data pointer points to.
using DeclsTy = SmallVector<NamedDecl *, 4>;
- /// \brief A collection of declarations, with a flag to indicate if we have
+ /// A collection of declarations, with a flag to indicate if we have
/// further external declarations.
using DeclsAndHasExternalTy = llvm::PointerIntPair<DeclsTy *, 1, bool>;
- /// \brief The stored data, which will be either a pointer to a NamedDecl,
+ /// The stored data, which will be either a pointer to a NamedDecl,
/// or a pointer to a vector with a flag to indicate if there are further
/// external declarations.
llvm::PointerUnion<NamedDecl *, DeclsAndHasExternalTy> Data;
@@ -122,7 +122,7 @@ public:
== Vec.end() && "list still contains decl");
}
- /// \brief Remove any declarations which were imported from an external
+ /// Remove any declarations which were imported from an external
/// AST source.
void removeExternalDecls() {
if (isNull()) {
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 5d1c6b86fe118..47fb68bf42d3e 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -148,13 +148,13 @@ public:
/// Retrieves the source range for the friend declaration.
SourceRange getSourceRange() const override LLVM_READONLY {
if (NamedDecl *ND = getFriendDecl()) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+ if (const auto *FD = dyn_cast<FunctionDecl>(ND))
return FD->getSourceRange();
- if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
+ if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
return FTD->getSourceRange();
- if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
+ if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
return CTD->getSourceRange();
- if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) {
+ if (const auto *DD = dyn_cast<DeclaratorDecl>(ND)) {
if (DD->getOuterLocStart() != DD->getInnerLocStart())
return DD->getSourceRange();
}
diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h
index 2fff055825632..64eb3f24b3701 100644
--- a/include/clang/AST/DeclLookups.h
+++ b/include/clang/AST/DeclLookups.h
@@ -86,16 +86,11 @@ inline DeclContext::lookups_range DeclContext::lookups() const {
return lookups_range(all_lookups_iterator(), all_lookups_iterator());
}
-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 {
+inline DeclContext::lookups_range
+DeclContext::noload_lookups(bool PreserveInternalState) const {
DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
+ if (!PreserveInternalState)
+ Primary->loadLazyLocalLexicalLookups();
if (StoredDeclsMap *Map = Primary->getLookupPtr())
return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
all_lookups_iterator(Map->end(), Map->end()));
@@ -105,16 +100,6 @@ inline DeclContext::lookups_range DeclContext::noload_lookups() const {
return lookups_range(all_lookups_iterator(), all_lookups_iterator());
}
-inline
-DeclContext::all_lookups_iterator DeclContext::noload_lookups_begin() const {
- return noload_lookups().begin();
-}
-
-inline
-DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const {
- return noload_lookups().end();
-}
-
} // namespace clang
#endif // LLVM_CLANG_AST_DECLLOOKUPS_H
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index cef7d935370a2..c81a5f805fc03 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -97,7 +97,7 @@ public:
}
};
-/// \brief A list of Objective-C protocols, along with the source
+/// A list of Objective-C protocols, along with the source
/// locations at which they were referenced.
class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
SourceLocation *Locations = nullptr;
@@ -156,10 +156,10 @@ private:
// Method has a definition.
unsigned IsDefined : 1;
- /// \brief Method redeclaration in the same interface.
+ /// Method redeclaration in the same interface.
unsigned IsRedeclaration : 1;
- /// \brief Is redeclared in the same interface.
+ /// Is redeclared in the same interface.
mutable unsigned HasRedeclaration : 1;
// NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
@@ -170,14 +170,14 @@ private:
/// in, inout, etc.
unsigned objcDeclQualifier : 7;
- /// \brief Indicates whether this method has a related result type.
+ /// Indicates whether this method has a related result type.
unsigned RelatedResultType : 1;
- /// \brief Whether the locations of the selector identifiers are in a
+ /// Whether the locations of the selector identifiers are in a
/// "standard" position, a enum SelectorLocationsKind.
unsigned SelLocsKind : 2;
- /// \brief Whether this method overrides any other in the class hierarchy.
+ /// Whether this method overrides any other in the class hierarchy.
///
/// A method is said to override any method in the class's
/// base classes, its protocols, or its categories' protocols, that has
@@ -186,7 +186,7 @@ private:
/// method in the interface or its categories.
unsigned IsOverriding : 1;
- /// \brief Indicates if the method was a definition but its body was skipped.
+ /// Indicates if the method was a definition but its body was skipped.
unsigned HasSkippedBody : 1;
// Return type of this method.
@@ -195,7 +195,7 @@ private:
// Type source information for the return type.
TypeSourceInfo *ReturnTInfo;
- /// \brief Array of ParmVarDecls for the formal parameters of this method
+ /// Array of ParmVarDecls for the formal parameters of this method
/// and optionally followed by selector locations.
void *ParamsAndSelLocs = nullptr;
unsigned NumParams = 0;
@@ -241,7 +241,7 @@ private:
return getSelLocsKind() != SelLoc_NonStandard;
}
- /// \brief Get a pointer to the stored selector identifiers locations array.
+ /// Get a pointer to the stored selector identifiers locations array.
/// No locations will be stored if HasStandardSelLocs is true.
SourceLocation *getStoredSelLocs() {
return reinterpret_cast<SourceLocation*>(getParams() + NumParams);
@@ -250,7 +250,7 @@ private:
return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
}
- /// \brief Get a pointer to the stored selector identifiers locations array.
+ /// Get a pointer to the stored selector identifiers locations array.
/// No locations will be stored if HasStandardSelLocs is true.
ParmVarDecl **getParams() {
return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs);
@@ -259,7 +259,7 @@ private:
return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs);
}
- /// \brief Get the number of stored selector identifiers locations.
+ /// Get the number of stored selector identifiers locations.
/// No locations will be stored if HasStandardSelLocs is true.
unsigned getNumStoredSelLocs() const {
if (hasStandardSelLocs())
@@ -271,7 +271,7 @@ private:
ArrayRef<ParmVarDecl*> Params,
ArrayRef<SourceLocation> SelLocs);
- /// \brief A definition will return its interface declaration.
+ /// A definition will return its interface declaration.
/// An interface declaration will return its definition.
/// Otherwise it will return itself.
ObjCMethodDecl *getNextRedeclarationImpl() override;
@@ -301,18 +301,18 @@ public:
}
void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
- /// \brief Determine whether this method has a result type that is related
+ /// Determine whether this method has a result type that is related
/// to the message receiver's type.
bool hasRelatedResultType() const { return RelatedResultType; }
- /// \brief Note whether this method has a related result type.
+ /// Note whether this method has a related result type.
void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
- /// \brief True if this is a method redeclaration in the same interface.
+ /// True if this is a method redeclaration in the same interface.
bool isRedeclaration() const { return IsRedeclaration; }
void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
- /// \brief Returns the location where the declarator ends. It will be
+ /// Returns the location where the declarator ends. It will be
/// the location of ';' for a method declaration and the location of '{'
/// for a method definition.
SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; }
@@ -362,7 +362,7 @@ public:
void setReturnType(QualType T) { MethodDeclType = T; }
SourceRange getReturnTypeSourceRange() const;
- /// \brief Determine the type of an expression that sends a message to this
+ /// Determine the type of an expression that sends a message to this
/// function. This replaces the type parameters with the types they would
/// get if the receiver was parameterless (e.g. it may replace the type
/// parameter with 'id').
@@ -407,7 +407,7 @@ public:
NumParams);
}
- /// \brief Sets the method's parameters and selector source locations.
+ /// Sets the method's parameters and selector source locations.
/// If the method is implicit (not coming from source) \p SelLocs is
/// ignored.
void setMethodParams(ASTContext &C,
@@ -462,7 +462,7 @@ public:
bool isDefined() const { return IsDefined; }
void setDefined(bool isDefined) { IsDefined = isDefined; }
- /// \brief Whether this method overrides any other in the class hierarchy.
+ /// Whether this method overrides any other in the class hierarchy.
///
/// A method is said to override any method in the class's
/// base classes, its protocols, or its categories' protocols, that has
@@ -472,7 +472,7 @@ public:
bool isOverriding() const { return IsOverriding; }
void setOverriding(bool isOverriding) { IsOverriding = isOverriding; }
- /// \brief Return overridden methods for the given \p Method.
+ /// Return overridden methods for the given \p Method.
///
/// An ObjC method is considered to override any method in the class's
/// base classes (and base's categories), its protocols, or its categories'
@@ -483,11 +483,11 @@ public:
void getOverriddenMethods(
SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
- /// \brief True if the method was a definition but its body was skipped.
+ /// True if the method was a definition but its body was skipped.
bool hasSkippedBody() const { return HasSkippedBody; }
void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
- /// \brief Returns the property associated with this method's selector.
+ /// Returns the property associated with this method's selector.
///
/// Note that even if this particular method is not marked as a property
/// accessor, it is still possible for it to match a property declared in a
@@ -520,10 +520,10 @@ public:
bool isDesignatedInitializerForTheInterface(
const ObjCMethodDecl **InitMethod = nullptr) const;
- /// \brief Determine whether this method has a body.
+ /// Determine whether this method has a body.
bool hasBody() const override { return Body.isValid(); }
- /// \brief Retrieve the body of this method, if it has one.
+ /// Retrieve the body of this method, if it has one.
Stmt *getBody() const override;
void setLazyBody(uint64_t Offset) { Body = Offset; }
@@ -531,7 +531,7 @@ public:
CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); }
void setBody(Stmt *B) { Body = B; }
- /// \brief Returns whether this specific method is a definition.
+ /// Returns whether this specific method is a definition.
bool isThisDeclarationADefinition() const { return hasBody(); }
// Implement isa/cast/dyncast/etc.
@@ -737,7 +737,7 @@ enum class ObjCPropertyQueryKind : uint8_t {
OBJC_PR_query_class
};
-/// \brief Represents one property declaration in an Objective-C interface.
+/// Represents one property declaration in an Objective-C interface.
///
/// For example:
/// \code{.mm}
@@ -770,7 +770,7 @@ public:
};
enum {
- /// \brief Number of bits fitting all the property attributes.
+ /// Number of bits fitting all the property attributes.
NumPropertyAttrsBits = 15
};
@@ -1163,7 +1163,7 @@ public:
}
};
-/// \brief Represents an ObjC class declaration.
+/// Represents an ObjC class declaration.
///
/// For example:
///
@@ -1197,7 +1197,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
mutable const Type *TypeForDecl = nullptr;
struct DefinitionData {
- /// \brief The definition of this class, for quick access from any
+ /// The definition of this class, for quick access from any
/// declaration.
ObjCInterfaceDecl *Definition = nullptr;
@@ -1210,7 +1210,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// Protocols reference in both the \@interface and class extensions.
ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
- /// \brief List of categories and class extensions defined for this class.
+ /// List of categories and class extensions defined for this class.
///
/// Categories are stored as a linked list in the AST, since the categories
/// and class extensions come long after the initial interface declaration,
@@ -1221,11 +1221,11 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// extensions and implementation. This list is built lazily.
ObjCIvarDecl *IvarList = nullptr;
- /// \brief Indicates that the contents of this Objective-C class will be
+ /// Indicates that the contents of this Objective-C class will be
/// completed by the external AST source when required.
mutable unsigned ExternallyCompleted : 1;
- /// \brief Indicates that the ivar cache does not yet include ivars
+ /// Indicates that the ivar cache does not yet include ivars
/// declared in the implementation.
mutable unsigned IvarListMissingImplementation : 1;
@@ -1248,7 +1248,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// One of the \c InheritedDesignatedInitializersState enumeratos.
mutable unsigned InheritedDesignatedInitializers : 2;
- /// \brief The location of the last location in this declaration, before
+ /// The location of the last location in this declaration, before
/// the properties/methods. For example, this will be the '>', '}', or
/// identifier,
SourceLocation EndLoc;
@@ -1262,7 +1262,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// The type parameters associated with this class, if any.
ObjCTypeParamList *TypeParamList = nullptr;
- /// \brief Contains a pointer to the data associated with this class,
+ /// Contains a pointer to the data associated with this class,
/// which will be NULL if this class has not yet been defined.
///
/// The bit indicates when we don't need to check for out-of-date
@@ -1283,7 +1283,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
return *Data.getPointer();
}
- /// \brief Allocate the definition data for this class.
+ /// Allocate the definition data for this class.
void allocateDefinitionData();
using redeclarable_base = Redeclarable<ObjCInterfaceDecl>;
@@ -1338,7 +1338,7 @@ public:
return SourceRange(getAtStartLoc(), getLocation());
}
- /// \brief Indicate that this Objective-C class is complete, but that
+ /// Indicate that this Objective-C class is complete, but that
/// the external AST source will be responsible for filling in its contents
/// when a complete class is required.
void setExternallyCompleted();
@@ -1544,13 +1544,13 @@ public:
isDesignatedInitializer(Selector Sel,
const ObjCMethodDecl **InitMethod = nullptr) const;
- /// \brief Determine whether this particular declaration of this class is
+ /// Determine whether this particular declaration of this class is
/// actually also a definition.
bool isThisDeclarationADefinition() const {
return getDefinition() == this;
}
- /// \brief Determine whether this class has been defined.
+ /// Determine whether this class has been defined.
bool hasDefinition() const {
// If the name of this class is out-of-date, bring it up-to-date, which
// might bring in a definition.
@@ -1562,21 +1562,21 @@ public:
return Data.getPointer();
}
- /// \brief Retrieve the definition of this class, or NULL if this class
+ /// Retrieve the definition of this class, or NULL if this class
/// has been forward-declared (with \@class) but not yet defined (with
/// \@interface).
ObjCInterfaceDecl *getDefinition() {
return hasDefinition()? Data.getPointer()->Definition : nullptr;
}
- /// \brief Retrieve the definition of this class, or NULL if this class
+ /// 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 : nullptr;
}
- /// \brief Starts the definition of this Objective-C class, taking it from
+ /// Starts the definition of this Objective-C class, taking it from
/// a forward declaration (\@class) to a definition (\@interface).
void startDefinition();
@@ -1608,7 +1608,7 @@ public:
data().SuperClassTInfo = superClass;
}
- /// \brief Iterator that walks over the list of categories, filtering out
+ /// Iterator that walks over the list of categories, filtering out
/// those that do not meet specific criteria.
///
/// This class template is used for the various permutations of category
@@ -1655,13 +1655,13 @@ public:
};
private:
- /// \brief Test whether the given category is visible.
+ /// Test whether the given category is visible.
///
/// Used in the \c visible_categories_iterator.
static bool isVisibleCategory(ObjCCategoryDecl *Cat);
public:
- /// \brief Iterator that walks over the list of categories and extensions
+ /// Iterator that walks over the list of categories and extensions
/// that are visible, i.e., not hidden in a non-imported submodule.
using visible_categories_iterator =
filtered_category_iterator<isVisibleCategory>;
@@ -1674,30 +1674,30 @@ public:
visible_categories_end());
}
- /// \brief Retrieve an iterator to the beginning of the visible-categories
+ /// Retrieve an iterator to the beginning of the visible-categories
/// list.
visible_categories_iterator visible_categories_begin() const {
return visible_categories_iterator(getCategoryListRaw());
}
- /// \brief Retrieve an iterator to the end of the visible-categories list.
+ /// Retrieve an iterator to the end of the visible-categories list.
visible_categories_iterator visible_categories_end() const {
return visible_categories_iterator();
}
- /// \brief Determine whether the visible-categories list is empty.
+ /// Determine whether the visible-categories list is empty.
bool visible_categories_empty() const {
return visible_categories_begin() == visible_categories_end();
}
private:
- /// \brief Test whether the given category... is a category.
+ /// Test whether the given category... is a category.
///
/// Used in the \c known_categories_iterator.
static bool isKnownCategory(ObjCCategoryDecl *) { return true; }
public:
- /// \brief Iterator that walks over all of the known categories and
+ /// Iterator that walks over all of the known categories and
/// extensions, including those that are hidden.
using known_categories_iterator = filtered_category_iterator<isKnownCategory>;
using known_categories_range =
@@ -1708,30 +1708,30 @@ public:
known_categories_end());
}
- /// \brief Retrieve an iterator to the beginning of the known-categories
+ /// Retrieve an iterator to the beginning of the known-categories
/// list.
known_categories_iterator known_categories_begin() const {
return known_categories_iterator(getCategoryListRaw());
}
- /// \brief Retrieve an iterator to the end of the known-categories list.
+ /// Retrieve an iterator to the end of the known-categories list.
known_categories_iterator known_categories_end() const {
return known_categories_iterator();
}
- /// \brief Determine whether the known-categories list is empty.
+ /// Determine whether the known-categories list is empty.
bool known_categories_empty() const {
return known_categories_begin() == known_categories_end();
}
private:
- /// \brief Test whether the given category is a visible extension.
+ /// Test whether the given category is a visible extension.
///
/// Used in the \c visible_extensions_iterator.
static bool isVisibleExtension(ObjCCategoryDecl *Cat);
public:
- /// \brief Iterator that walks over all of the visible extensions, skipping
+ /// Iterator that walks over all of the visible extensions, skipping
/// any that are known but hidden.
using visible_extensions_iterator =
filtered_category_iterator<isVisibleExtension>;
@@ -1744,24 +1744,24 @@ public:
visible_extensions_end());
}
- /// \brief Retrieve an iterator to the beginning of the visible-extensions
+ /// Retrieve an iterator to the beginning of the visible-extensions
/// list.
visible_extensions_iterator visible_extensions_begin() const {
return visible_extensions_iterator(getCategoryListRaw());
}
- /// \brief Retrieve an iterator to the end of the visible-extensions list.
+ /// Retrieve an iterator to the end of the visible-extensions list.
visible_extensions_iterator visible_extensions_end() const {
return visible_extensions_iterator();
}
- /// \brief Determine whether the visible-extensions list is empty.
+ /// Determine whether the visible-extensions list is empty.
bool visible_extensions_empty() const {
return visible_extensions_begin() == visible_extensions_end();
}
private:
- /// \brief Test whether the given category is an extension.
+ /// Test whether the given category is an extension.
///
/// Used in the \c known_extensions_iterator.
static bool isKnownExtension(ObjCCategoryDecl *Cat);
@@ -1771,7 +1771,7 @@ public:
friend class ASTDeclWriter;
friend class ASTReader;
- /// \brief Iterator that walks over all of the known extensions.
+ /// Iterator that walks over all of the known extensions.
using known_extensions_iterator =
filtered_category_iterator<isKnownExtension>;
using known_extensions_range =
@@ -1782,23 +1782,23 @@ public:
known_extensions_end());
}
- /// \brief Retrieve an iterator to the beginning of the known-extensions
+ /// Retrieve an iterator to the beginning of the known-extensions
/// list.
known_extensions_iterator known_extensions_begin() const {
return known_extensions_iterator(getCategoryListRaw());
}
- /// \brief Retrieve an iterator to the end of the known-extensions list.
+ /// Retrieve an iterator to the end of the known-extensions list.
known_extensions_iterator known_extensions_end() const {
return known_extensions_iterator();
}
- /// \brief Determine whether the known-extensions list is empty.
+ /// Determine whether the known-extensions list is empty.
bool known_extensions_empty() const {
return known_extensions_begin() == known_extensions_end();
}
- /// \brief Retrieve the raw pointer to the start of the category/extension
+ /// Retrieve the raw pointer to the start of the category/extension
/// list.
ObjCCategoryDecl* getCategoryListRaw() const {
// FIXME: Should make sure no callers ever do this.
@@ -1811,7 +1811,7 @@ public:
return data().CategoryList;
}
- /// \brief Set the raw pointer to the start of the category/extension
+ /// Set the raw pointer to the start of the category/extension
/// list.
void setCategoryListRaw(ObjCCategoryDecl *category) {
data().CategoryList = category;
@@ -1874,7 +1874,7 @@ public:
ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
- /// \brief Lookup a method in the classes implementation hierarchy.
+ /// Lookup a method in the classes implementation hierarchy.
ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel,
bool Instance=true) const;
@@ -1882,7 +1882,7 @@ public:
return lookupPrivateMethod(Sel, false);
}
- /// \brief Lookup a setter or getter in the class hierarchy,
+ /// Lookup a setter or getter in the class hierarchy,
/// including in all categories except for category passed
/// as argument.
ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
@@ -1988,7 +1988,7 @@ public:
static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- /// \brief Return the class interface that this ivar is logically contained
+ /// Return the class interface that this ivar is logically contained
/// in; this is either the interface where the ivar was declared, or the
/// interface the ivar is conceptually a part of in the case of synthesized
/// ivars.
@@ -2027,7 +2027,7 @@ private:
unsigned Synthesized : 1;
};
-/// \brief Represents a field declaration created by an \@defs(...).
+/// Represents a field declaration created by an \@defs(...).
class ObjCAtDefsFieldDecl : public FieldDecl {
ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
@@ -2051,7 +2051,7 @@ public:
static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
};
-/// \brief Represents an Objective-C protocol declaration.
+/// Represents an Objective-C protocol declaration.
///
/// Objective-C protocols declare a pure abstract type (i.e., no instance
/// variables are permitted). Protocols originally drew inspiration from
@@ -2083,14 +2083,14 @@ public:
class ObjCProtocolDecl : public ObjCContainerDecl,
public Redeclarable<ObjCProtocolDecl> {
struct DefinitionData {
- // \brief The declaration that defines this protocol.
+ // The declaration that defines this protocol.
ObjCProtocolDecl *Definition;
- /// \brief Referenced protocols
+ /// Referenced protocols
ObjCProtocolList ReferencedProtocols;
};
- /// \brief Contains a pointer to the data associated with this class,
+ /// Contains a pointer to the data associated with this class,
/// which will be NULL if this class has not yet been defined.
///
/// The bit indicates when we don't need to check for out-of-date
@@ -2213,7 +2213,7 @@ public:
return lookupMethod(Sel, false/*isInstance*/);
}
- /// \brief Determine whether this protocol has a definition.
+ /// Determine whether this protocol has a definition.
bool hasDefinition() const {
// If the name of this protocol is out-of-date, bring it up-to-date, which
// might bring in a definition.
@@ -2225,23 +2225,23 @@ public:
return Data.getPointer();
}
- /// \brief Retrieve the definition of this protocol, if any.
+ /// Retrieve the definition of this protocol, if any.
ObjCProtocolDecl *getDefinition() {
return hasDefinition()? Data.getPointer()->Definition : nullptr;
}
- /// \brief Retrieve the definition of this protocol, if any.
+ /// Retrieve the definition of this protocol, if any.
const ObjCProtocolDecl *getDefinition() const {
return hasDefinition()? Data.getPointer()->Definition : nullptr;
}
- /// \brief Determine whether this particular declaration is also the
+ /// Determine whether this particular declaration is also the
/// definition.
bool isThisDeclarationADefinition() const {
return getDefinition() == this;
}
- /// \brief Starts the definition of this Objective-C protocol.
+ /// Starts the definition of this Objective-C protocol.
void startDefinition();
/// Produce a name to be used for protocol's metadata. It comes either via
@@ -2310,7 +2310,7 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
/// FIXME: this should not be a singly-linked list. Move storage elsewhere.
ObjCCategoryDecl *NextClassCategory = nullptr;
- /// \brief The location of the category name in this declaration.
+ /// The location of the category name in this declaration.
SourceLocation CategoryNameLoc;
/// class extension may have private ivars.
@@ -2400,7 +2400,7 @@ public:
ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
- /// \brief Retrieve the pointer to the next stored category (or extension),
+ /// Retrieve the pointer to the next stored category (or extension),
/// which may be hidden.
ObjCCategoryDecl *getNextClassCategoryRaw() const {
return NextClassCategory;
@@ -2578,7 +2578,7 @@ class ObjCImplementationDecl : public ObjCImplDecl {
SourceLocation IvarRBraceLoc;
/// Support for ivar initialization.
- /// \brief The arguments used to initialize the ivars
+ /// The arguments used to initialize the ivars
LazyCXXCtorInitializersPtr IvarInitializers;
unsigned NumIvarInitializers = 0;
@@ -2694,7 +2694,7 @@ public:
return getIdentifier()->getName();
}
- /// @brief Get the name of the class associated with this interface.
+ /// Get the name of the class associated with this interface.
//
// FIXME: Move to StringRef API.
std::string getNameAsString() const {
@@ -2785,7 +2785,7 @@ public:
private:
SourceLocation AtLoc; // location of \@synthesize or \@dynamic
- /// \brief For \@synthesize, the location of the ivar, if it was written in
+ /// For \@synthesize, the location of the ivar, if it was written in
/// the source code.
///
/// \code
@@ -2854,7 +2854,7 @@ public:
this->IvarLoc = IvarLoc;
}
- /// \brief For \@synthesize, returns true if an ivar name was explicitly
+ /// For \@synthesize, returns true if an ivar name was explicitly
/// specified.
///
/// \code
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index 2a329c3732cb6..bec3acffc4332 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief This file defines OpenMP nodes for declarative directives.
+/// This file defines OpenMP nodes for declarative directives.
///
//===----------------------------------------------------------------------===//
@@ -24,7 +24,7 @@
namespace clang {
-/// \brief This represents '#pragma omp threadprivate ...' directive.
+/// This represents '#pragma omp threadprivate ...' directive.
/// For example, in the following, both 'a' and 'A::b' are threadprivate:
///
/// \code
@@ -89,7 +89,7 @@ public:
static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
};
-/// \brief This represents '#pragma omp declare reduction ...' directive.
+/// This represents '#pragma omp declare reduction ...' directive.
/// For example, in the following, declared reduction 'foo' for types 'int' and
/// 'float':
///
@@ -109,14 +109,14 @@ public:
private:
friend class ASTDeclReader;
- /// \brief Combiner for declare reduction construct.
+ /// Combiner for declare reduction construct.
Expr *Combiner;
- /// \brief Initializer for declare reduction construct.
+ /// Initializer for declare reduction construct.
Expr *Initializer;
/// Kind of initializer - function call or omp_priv<init_expr> initializtion.
InitKind InitializerKind = CallInit;
- /// \brief Reference to the previous declare reduction construct in the same
+ /// Reference to the previous declare reduction construct in the same
/// scope with the same name. Required for proper templates instantiation if
/// the declare reduction construct is declared inside compound statement.
LazyDeclPtr PrevDeclInScope;
@@ -135,33 +135,33 @@ private:
}
public:
- /// \brief Create declare reduction node.
+ /// Create declare reduction node.
static OMPDeclareReductionDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
- /// \brief Create deserialized declare reduction node.
+ /// Create deserialized declare reduction node.
static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
unsigned ID);
- /// \brief Get combiner expression of the declare reduction construct.
+ /// Get combiner expression of the declare reduction construct.
Expr *getCombiner() { return Combiner; }
const Expr *getCombiner() const { return Combiner; }
- /// \brief Set combiner expression for the declare reduction construct.
+ /// Set combiner expression for the declare reduction construct.
void setCombiner(Expr *E) { Combiner = E; }
- /// \brief Get initializer expression (if specified) of the declare reduction
+ /// Get initializer expression (if specified) of the declare reduction
/// construct.
Expr *getInitializer() { return Initializer; }
const Expr *getInitializer() const { return Initializer; }
/// Get initializer kind.
InitKind getInitializerKind() const { return InitializerKind; }
- /// \brief Set initializer expression for the declare reduction construct.
+ /// Set initializer expression for the declare reduction construct.
void setInitializer(Expr *E, InitKind IK) {
Initializer = E;
InitializerKind = IK;
}
- /// \brief Get reference to previous declare reduction construct in the same
+ /// Get reference to previous declare reduction construct in the same
/// scope with the same name.
OMPDeclareReductionDecl *getPrevDeclInScope();
const OMPDeclareReductionDecl *getPrevDeclInScope() const;
@@ -189,9 +189,10 @@ class OMPCapturedExprDecl final : public VarDecl {
void anchor() override;
OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
- QualType Type, SourceLocation StartLoc)
- : VarDecl(OMPCapturedExpr, C, DC, StartLoc, SourceLocation(), Id, Type,
- nullptr, SC_None) {
+ QualType Type, TypeSourceInfo *TInfo,
+ SourceLocation StartLoc)
+ : VarDecl(OMPCapturedExpr, C, DC, StartLoc, StartLoc, Id, Type, TInfo,
+ SC_None) {
setImplicit();
}
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 7842d70971747..a2f00ec9ffa22 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Defines the C++ template declaration subclasses.
+/// Defines the C++ template declaration subclasses.
//
//===----------------------------------------------------------------------===//
@@ -56,14 +56,14 @@ class UnresolvedSetImpl;
class VarTemplateDecl;
class VarTemplatePartialSpecializationDecl;
-/// \brief Stores a template parameter of any kind.
+/// Stores a template parameter of any kind.
using TemplateParameter =
llvm::PointerUnion3<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *,
TemplateTemplateParmDecl *>;
NamedDecl *getAsNamedDecl(TemplateParameter P);
-/// \brief Stores a list of template parameters for a TemplateDecl and its
+/// Stores a list of template parameters for a TemplateDecl and its
/// derived classes.
class TemplateParameterList final
: private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
@@ -110,10 +110,10 @@ public:
SourceLocation RAngleLoc,
Expr *RequiresClause);
- /// \brief Iterates through the template parameters in this list.
+ /// Iterates through the template parameters in this list.
using iterator = NamedDecl **;
- /// \brief Iterates through the template parameters in this list.
+ /// Iterates through the template parameters in this list.
using const_iterator = NamedDecl * const *;
iterator begin() { return getTrailingObjects<NamedDecl *>(); }
@@ -139,32 +139,32 @@ public:
return begin()[Idx];
}
- /// \brief Returns the minimum number of arguments needed to form a
+ /// Returns the minimum number of arguments needed to form a
/// template specialization.
///
/// This may be fewer than the number of template parameters, if some of
/// the parameters have default arguments or if there is a parameter pack.
unsigned getMinRequiredArguments() const;
- /// \brief Get the depth of this template parameter list in the set of
+ /// Get the depth of this template parameter list in the set of
/// template parameter lists.
///
/// The first template parameter list in a declaration will have depth 0,
/// the second template parameter list will have depth 1, etc.
unsigned getDepth() const;
- /// \brief Determine whether this template parameter list contains an
+ /// Determine whether this template parameter list contains an
/// unexpanded parameter pack.
bool containsUnexpandedParameterPack() const {
return ContainsUnexpandedParameterPack;
}
- /// \brief The constraint-expression of the associated requires-clause.
+ /// The constraint-expression of the associated requires-clause.
Expr *getRequiresClause() {
return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr;
}
- /// \brief The constraint-expression of the associated requires-clause.
+ /// The constraint-expression of the associated requires-clause.
const Expr *getRequiresClause() const {
return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr;
}
@@ -182,7 +182,7 @@ public:
using FixedSizeStorageOwner = TrailingObjects::FixedSizeStorageOwner;
};
-/// \brief Stores a list of template parameters and the associated
+/// Stores a list of template parameters and the associated
/// requires-clause (if any) for a TemplateDecl and its derived classes.
/// Suitable for creating on the stack.
template <size_t N, bool HasRequiresClause>
@@ -206,13 +206,13 @@ public:
TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
};
-/// \brief A template argument list.
+/// A template argument list.
class TemplateArgumentList final
: private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
- /// \brief The template argument list.
+ /// The template argument list.
const TemplateArgument *Arguments;
- /// \brief The number of template arguments in this template
+ /// The number of template arguments in this template
/// argument list.
unsigned NumArguments;
@@ -226,23 +226,23 @@ public:
TemplateArgumentList(const TemplateArgumentList &) = delete;
TemplateArgumentList &operator=(const TemplateArgumentList &) = delete;
- /// \brief Type used to indicate that the template argument list itself is a
+ /// Type used to indicate that the template argument list itself is a
/// stack object. It does not own its template arguments.
enum OnStackType { OnStack };
- /// \brief Create a new template argument list that copies the given set of
+ /// Create a new template argument list that copies the given set of
/// template arguments.
static TemplateArgumentList *CreateCopy(ASTContext &Context,
ArrayRef<TemplateArgument> Args);
- /// \brief Construct a new, temporary template argument list on the stack.
+ /// Construct a new, temporary template argument list on the stack.
///
/// The template argument list does not own the template arguments
/// provided.
explicit TemplateArgumentList(OnStackType, ArrayRef<TemplateArgument> Args)
: Arguments(Args.data()), NumArguments(Args.size()) {}
- /// \brief Produces a shallow copy of the given template argument list.
+ /// Produces a shallow copy of the given template argument list.
///
/// This operation assumes that the input argument list outlives it.
/// This takes the list as a pointer to avoid looking like a copy
@@ -251,25 +251,25 @@ public:
explicit TemplateArgumentList(const TemplateArgumentList *Other)
: Arguments(Other->data()), NumArguments(Other->size()) {}
- /// \brief Retrieve the template argument at a given index.
+ /// Retrieve the template argument at a given index.
const TemplateArgument &get(unsigned Idx) const {
assert(Idx < NumArguments && "Invalid template argument index");
return data()[Idx];
}
- /// \brief Retrieve the template argument at a given index.
+ /// Retrieve the template argument at a given index.
const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
- /// \brief Produce this as an array ref.
+ /// Produce this as an array ref.
ArrayRef<TemplateArgument> asArray() const {
return llvm::makeArrayRef(data(), size());
}
- /// \brief Retrieve the number of template arguments in this
+ /// Retrieve the number of template arguments in this
/// template argument list.
unsigned size() const { return NumArguments; }
- /// \brief Retrieve a pointer to the template argument list.
+ /// Retrieve a pointer to the template argument list.
const TemplateArgument *data() const { return Arguments; }
};
@@ -299,7 +299,7 @@ class DefaultArgStorage {
static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
- if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl*>())
+ if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl *>())
Parm = Prev;
assert(!Parm->getDefaultArgStorage()
.ValueOrInherited.template is<ParmDecl *>() &&
@@ -321,9 +321,9 @@ public:
/// default argument is visible.
ArgType get() const {
const DefaultArgStorage *Storage = this;
- if (auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl*>())
+ if (const auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl *>())
Storage = &Prev->getDefaultArgStorage();
- if (auto *C = Storage->ValueOrInherited.template dyn_cast<Chain*>())
+ if (const auto *C = Storage->ValueOrInherited.template dyn_cast<Chain *>())
return C->Value;
return Storage->ValueOrInherited.template get<ArgType>();
}
@@ -331,9 +331,9 @@ public:
/// Get the parameter from which we inherit the default argument, if any.
/// This is the parameter on which the default argument was actually written.
const ParmDecl *getInheritedFrom() const {
- if (auto *D = ValueOrInherited.template dyn_cast<ParmDecl*>())
+ if (const auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>())
return D;
- if (auto *C = ValueOrInherited.template dyn_cast<Chain*>())
+ if (const auto *C = ValueOrInherited.template dyn_cast<Chain *>())
return C->PrevDeclWithDefaultArg;
return nullptr;
}
@@ -365,7 +365,7 @@ public:
// Kinds of Templates
//===----------------------------------------------------------------------===//
-/// \brief Stores the template parameter list and associated constraints for
+/// Stores the template parameter list and associated constraints for
/// \c TemplateDecl objects that track associated constraints.
class ConstrainedTemplateDeclInfo {
friend TemplateDecl;
@@ -391,7 +391,7 @@ protected:
};
-/// \brief The base class of all kinds of template declarations (e.g.,
+/// The base class of all kinds of template declarations (e.g.,
/// class, function, etc.).
///
/// The TemplateDecl class stores the list of template parameters and a
@@ -443,7 +443,7 @@ public:
}
Expr *getAssociatedConstraints() const {
- const TemplateDecl *const C = cast<TemplateDecl>(getCanonicalDecl());
+ const auto *const C = cast<TemplateDecl>(getCanonicalDecl());
const auto *const CTDI =
C->TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
return CTDI ? CTDI->getAssociatedConstraints() : nullptr;
@@ -466,7 +466,8 @@ public:
protected:
NamedDecl *TemplatedDecl;
- /// \brief The template parameter list and optional requires-clause
+
+ /// The template parameter list and optional requires-clause
/// associated with this declaration; alternatively, a
/// \c ConstrainedTemplateDeclInfo if the associated constraints of the
/// template are being tracked by this particular declaration.
@@ -491,7 +492,7 @@ protected:
}
public:
- /// \brief Initialize the underlying templated declaration and
+ /// Initialize the underlying templated declaration and
/// template parameters.
void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
assert(!TemplatedDecl && "TemplatedDecl already set!");
@@ -501,7 +502,7 @@ public:
}
};
-/// \brief Provides information about a function template specialization,
+/// Provides information about a function template specialization,
/// which is a FunctionDecl that has been explicitly specialization or
/// instantiated from a function template.
class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
@@ -524,31 +525,31 @@ public:
const TemplateArgumentListInfo *TemplateArgsAsWritten,
SourceLocation POI);
- /// \brief The function template specialization that this structure
+ /// The function template specialization that this structure
/// describes.
FunctionDecl *Function;
- /// \brief The function template from which this function template
+ /// The function template from which this function template
/// specialization was generated.
///
/// The two bits contain the top 4 values of TemplateSpecializationKind.
llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
- /// \brief The template arguments used to produce the function template
+ /// The template arguments used to produce the function template
/// specialization from the function template.
const TemplateArgumentList *TemplateArguments;
- /// \brief The template arguments as written in the sources, if provided.
+ /// The template arguments as written in the sources, if provided.
const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
- /// \brief The point at which this function template specialization was
+ /// The point at which this function template specialization was
/// first instantiated.
SourceLocation PointOfInstantiation;
- /// \brief Retrieve the template from which this function was specialized.
+ /// Retrieve the template from which this function was specialized.
FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
- /// \brief Determine what kind of template specialization this is.
+ /// Determine what kind of template specialization this is.
TemplateSpecializationKind getTemplateSpecializationKind() const {
return (TemplateSpecializationKind)(Template.getInt() + 1);
}
@@ -557,7 +558,7 @@ public:
return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
}
- /// \brief True if this declaration is an explicit specialization,
+ /// True if this declaration is an explicit specialization,
/// explicit instantiation declaration, or explicit instantiation
/// definition.
bool isExplicitInstantiationOrSpecialization() const {
@@ -565,14 +566,14 @@ public:
getTemplateSpecializationKind());
}
- /// \brief Set the template specialization kind.
+ /// Set the template specialization kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
assert(TSK != TSK_Undeclared &&
"Cannot encode TSK_Undeclared for a function template specialization");
Template.setInt(TSK - 1);
}
- /// \brief Retrieve the first point of instantiation of this function
+ /// Retrieve the first point of instantiation of this function
/// template specialization.
///
/// The point of instantiation may be an invalid source location if this
@@ -581,7 +582,7 @@ public:
return PointOfInstantiation;
}
- /// \brief Set the (first) point of instantiation of this function template
+ /// Set the (first) point of instantiation of this function template
/// specialization.
void setPointOfInstantiation(SourceLocation POI) {
PointOfInstantiation = POI;
@@ -601,7 +602,7 @@ public:
}
};
-/// \brief Provides information a specialization of a member of a class
+/// Provides information a specialization of a member of a class
/// template, which may be a member function, static data member,
/// member class or member enumeration.
class MemberSpecializationInfo {
@@ -621,11 +622,11 @@ public:
"Cannot encode undeclared template specializations for members");
}
- /// \brief Retrieve the member declaration from which this member was
+ /// Retrieve the member declaration from which this member was
/// instantiated.
NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
- /// \brief Determine what kind of template specialization this is.
+ /// Determine what kind of template specialization this is.
TemplateSpecializationKind getTemplateSpecializationKind() const {
return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
}
@@ -634,27 +635,27 @@ public:
return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
}
- /// \brief Set the template specialization kind.
+ /// Set the template specialization kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
assert(TSK != TSK_Undeclared &&
"Cannot encode undeclared template specializations for members");
MemberAndTSK.setInt(TSK - 1);
}
- /// \brief Retrieve the first point of instantiation of this member.
+ /// Retrieve the first point of instantiation of this member.
/// If the point of instantiation is an invalid location, then this member
/// has not yet been instantiated.
SourceLocation getPointOfInstantiation() const {
return PointOfInstantiation;
}
- /// \brief Set the first point of instantiation.
+ /// Set the first point of instantiation.
void setPointOfInstantiation(SourceLocation POI) {
PointOfInstantiation = POI;
}
};
-/// \brief Provides information about a dependent function-template
+/// Provides information about a dependent function-template
/// specialization declaration.
///
/// Since explicit function template specialization and instantiation
@@ -699,25 +700,25 @@ public:
Create(ASTContext &Context, const UnresolvedSetImpl &Templates,
const TemplateArgumentListInfo &TemplateArgs);
- /// \brief Returns the number of function templates that this might
+ /// Returns the number of function templates that this might
/// be a specialization of.
unsigned getNumTemplates() const { return NumTemplates; }
- /// \brief Returns the i'th template candidate.
+ /// Returns the i'th template candidate.
FunctionTemplateDecl *getTemplate(unsigned I) const {
assert(I < getNumTemplates() && "template index out of range");
return getTrailingObjects<FunctionTemplateDecl *>()[I];
}
- /// \brief Returns the explicit template arguments that were given.
+ /// Returns the explicit template arguments that were given.
const TemplateArgumentLoc *getTemplateArgs() const {
return getTrailingObjects<TemplateArgumentLoc>();
}
- /// \brief Returns the number of explicit template arguments that were given.
+ /// Returns the number of explicit template arguments that were given.
unsigned getNumTemplateArgs() const { return NumArgs; }
- /// \brief Returns the nth template argument.
+ /// Returns the nth template argument.
const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
assert(I < getNumTemplateArgs() && "template arg index out of range");
return getTemplateArgs()[I];
@@ -803,7 +804,7 @@ protected:
struct CommonBase {
CommonBase() : InstantiatedFromMember(nullptr, false) {}
- /// \brief The template from which this was most
+ /// The template from which this was most
/// directly instantiated (or null).
///
/// The boolean value indicates whether this template
@@ -811,7 +812,7 @@ protected:
llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
InstantiatedFromMember;
- /// \brief If non-null, points to an array of specializations (including
+ /// If non-null, points to an array of specializations (including
/// partial specializations) known only by their external declaration IDs.
///
/// The first value in the array is the number of specializations/partial
@@ -819,11 +820,11 @@ protected:
uint32_t *LazySpecializations = nullptr;
};
- /// \brief Pointer to the common data shared by all declarations of this
+ /// Pointer to the common data shared by all declarations of this
/// template.
mutable CommonBase *Common = nullptr;
- /// \brief Retrieves the "common" pointer shared by all (re-)declarations of
+ /// Retrieves the "common" pointer shared by all (re-)declarations of
/// the same template. Calling this routine may implicitly allocate memory
/// for the common pointer.
CommonBase *getCommonPtr() const;
@@ -849,7 +850,7 @@ public:
friend class ASTReader;
template <class decl_type> friend class RedeclarableTemplate;
- /// \brief Retrieves the canonical declaration of this template.
+ /// Retrieves the canonical declaration of this template.
RedeclarableTemplateDecl *getCanonicalDecl() override {
return getFirstDecl();
}
@@ -857,7 +858,7 @@ public:
return getFirstDecl();
}
- /// \brief Determines whether this template was a specialization of a
+ /// Determines whether this template was a specialization of a
/// member template.
///
/// In the following example, the function template \c X<int>::f and the
@@ -879,14 +880,14 @@ public:
return getCommonPtr()->InstantiatedFromMember.getInt();
}
- /// \brief Note that this member template is a specialization.
+ /// Note that this member template is a specialization.
void setMemberSpecialization() {
assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
"Only member templates can be member template specializations");
getCommonPtr()->InstantiatedFromMember.setInt(true);
}
- /// \brief Retrieve the member template from which this template was
+ /// Retrieve the member template from which this template was
/// instantiated, or nullptr if this template was not instantiated from a
/// member template.
///
@@ -968,14 +969,14 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl {
protected:
friend class FunctionDecl;
- /// \brief Data that is common to all of the declarations of a given
+ /// Data that is common to all of the declarations of a given
/// function template.
struct Common : CommonBase {
- /// \brief The function template specializations for this function
+ /// The function template specializations for this function
/// template, including explicit specializations and instantiations.
llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
- /// \brief The set of "injected" template arguments used within this
+ /// The set of "injected" template arguments used within this
/// function template.
///
/// This pointer refers to the template arguments (there are as
@@ -999,12 +1000,12 @@ protected:
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
}
- /// \brief Retrieve the set of function template specializations of this
+ /// Retrieve the set of function template specializations of this
/// function template.
llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
getSpecializations() const;
- /// \brief Add a specialization of this function template.
+ /// Add a specialization of this function template.
///
/// \param InsertPos Insert position in the FoldingSetVector, must have been
/// retrieved by an earlier call to findSpecialization().
@@ -1015,7 +1016,7 @@ public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
- /// \brief Load any lazily-loaded specializations from the external source.
+ /// Load any lazily-loaded specializations from the external source.
void LoadLazySpecializations() const;
/// Get the underlying function declaration of the template.
@@ -1029,7 +1030,7 @@ public:
return getTemplatedDecl()->isThisDeclarationADefinition();
}
- /// \brief Return the specialization with the provided arguments if it exists,
+ /// Return the specialization with the provided arguments if it exists,
/// otherwise return the insertion point.
FunctionDecl *findSpecialization(ArrayRef<TemplateArgument> Args,
void *&InsertPos);
@@ -1043,7 +1044,7 @@ public:
RedeclarableTemplateDecl::getCanonicalDecl());
}
- /// \brief Retrieve the previous declaration of this function template, or
+ /// Retrieve the previous declaration of this function template, or
/// nullptr if no such declaration exists.
FunctionTemplateDecl *getPreviousDecl() {
return cast_or_null<FunctionTemplateDecl>(
@@ -1083,7 +1084,7 @@ public:
return makeSpecIterator(getSpecializations(), true);
}
- /// \brief Retrieve the "injected" template arguments that correspond to the
+ /// Retrieve the "injected" template arguments that correspond to the
/// template parameters of this function template.
///
/// Although the C++ standard has no notion of the "injected" template
@@ -1092,14 +1093,14 @@ public:
/// template.
ArrayRef<TemplateArgument> getInjectedTemplateArgs();
- /// \brief Create a function template node.
+ /// Create a function template node.
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl);
- /// \brief Create an empty function template node.
+ /// Create an empty function template node.
static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
// Implement isa/cast/dyncast support
@@ -1111,7 +1112,7 @@ public:
// Kinds of Template Parameters
//===----------------------------------------------------------------------===//
-/// \brief Defines the position of a template parameter within a template
+/// Defines the position of a template parameter within a template
/// parameter list.
///
/// Because template parameter can be listed
@@ -1144,7 +1145,7 @@ public:
unsigned getIndex() const { return Position; }
};
-/// \brief Declaration of a template type parameter.
+/// Declaration of a template type parameter.
///
/// For example, "T" in
/// \code
@@ -1154,13 +1155,13 @@ class TemplateTypeParmDecl : public TypeDecl {
/// Sema creates these on the stack during auto type deduction.
friend class Sema;
- /// \brief Whether this template type parameter was declaration with
+ /// Whether this template type parameter was declaration with
/// the 'typename' keyword.
///
/// If false, it was declared with the 'class' keyword.
bool Typename : 1;
- /// \brief The default template argument, if any.
+ /// The default template argument, if any.
using DefArgStorage =
DefaultArgStorage<TemplateTypeParmDecl, TypeSourceInfo *>;
DefArgStorage DefaultArgument;
@@ -1180,7 +1181,7 @@ public:
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
unsigned ID);
- /// \brief Whether this template type parameter was declared with
+ /// Whether this template type parameter was declared with
/// the 'typename' keyword.
///
/// If not, it was declared with the 'class' keyword.
@@ -1188,57 +1189,57 @@ public:
const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
- /// \brief Determine whether this template parameter has a default
+ /// Determine whether this template parameter has a default
/// argument.
bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
- /// \brief Retrieve the default argument, if any.
+ /// Retrieve the default argument, if any.
QualType getDefaultArgument() const {
return DefaultArgument.get()->getType();
}
- /// \brief Retrieves the default argument's source information, if any.
+ /// Retrieves the default argument's source information, if any.
TypeSourceInfo *getDefaultArgumentInfo() const {
return DefaultArgument.get();
}
- /// \brief Retrieves the location of the default argument declaration.
+ /// Retrieves the location of the default argument declaration.
SourceLocation getDefaultArgumentLoc() const;
- /// \brief Determines whether the default argument was inherited
+ /// Determines whether the default argument was inherited
/// from a previous declaration of this template.
bool defaultArgumentWasInherited() const {
return DefaultArgument.isInherited();
}
- /// \brief Set the default argument for this template parameter.
+ /// Set the default argument for this template parameter.
void setDefaultArgument(TypeSourceInfo *DefArg) {
DefaultArgument.set(DefArg);
}
- /// \brief Set that this default argument was inherited from another
+ /// Set that this default argument was inherited from another
/// parameter.
void setInheritedDefaultArgument(const ASTContext &C,
TemplateTypeParmDecl *Prev) {
DefaultArgument.setInherited(C, Prev);
}
- /// \brief Removes the default argument of this template parameter.
+ /// Removes the default argument of this template parameter.
void removeDefaultArgument() {
DefaultArgument.clear();
}
- /// \brief Set whether this template type parameter was declared with
+ /// Set whether this template type parameter was declared with
/// the 'typename' or 'class' keyword.
void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
- /// \brief Retrieve the depth of the template parameter.
+ /// Retrieve the depth of the template parameter.
unsigned getDepth() const;
- /// \brief Retrieve the index of the template parameter.
+ /// Retrieve the index of the template parameter.
unsigned getIndex() const;
- /// \brief Returns whether this is a parameter pack.
+ /// Returns whether this is a parameter pack.
bool isParameterPack() const;
SourceRange getSourceRange() const override LLVM_READONLY;
@@ -1261,7 +1262,7 @@ class NonTypeTemplateParmDecl final
friend class ASTDeclReader;
friend TrailingObjects;
- /// \brief The default template argument, if any, and whether or not
+ /// The default template argument, if any, and whether or not
/// it was inherited.
using DefArgStorage = DefaultArgStorage<NonTypeTemplateParmDecl, Expr *>;
DefArgStorage DefaultArgument;
@@ -1269,15 +1270,15 @@ class NonTypeTemplateParmDecl final
// FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
// down here to save memory.
- /// \brief Whether this non-type template parameter is a parameter pack.
+ /// Whether this non-type template parameter is a parameter pack.
bool ParameterPack;
- /// \brief Whether this non-type template parameter is an "expanded"
+ /// Whether this non-type template parameter is an "expanded"
/// parameter pack, meaning that its type is a pack expansion and we
/// already know the set of types that expansion expands to.
bool ExpandedParameterPack = false;
- /// \brief The number of types in an expanded parameter pack.
+ /// The number of types in an expanded parameter pack.
unsigned NumExpandedTypes = 0;
size_t numTrailingObjects(
@@ -1327,23 +1328,23 @@ public:
const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
- /// \brief Determine whether this template parameter has a default
+ /// Determine whether this template parameter has a default
/// argument.
bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
- /// \brief Retrieve the default argument, if any.
+ /// Retrieve the default argument, if any.
Expr *getDefaultArgument() const { return DefaultArgument.get(); }
- /// \brief Retrieve the location of the default argument, if any.
+ /// Retrieve the location of the default argument, if any.
SourceLocation getDefaultArgumentLoc() const;
- /// \brief Determines whether the default argument was inherited
+ /// Determines whether the default argument was inherited
/// from a previous declaration of this template.
bool defaultArgumentWasInherited() const {
return DefaultArgument.isInherited();
}
- /// \brief Set the default argument for this template parameter, and
+ /// Set the default argument for this template parameter, and
/// whether that default argument was inherited from another
/// declaration.
void setDefaultArgument(Expr *DefArg) { DefaultArgument.set(DefArg); }
@@ -1352,10 +1353,10 @@ public:
DefaultArgument.setInherited(C, Parm);
}
- /// \brief Removes the default argument of this template parameter.
+ /// Removes the default argument of this template parameter.
void removeDefaultArgument() { DefaultArgument.clear(); }
- /// \brief Whether this parameter is a non-type template parameter pack.
+ /// Whether this parameter is a non-type template parameter pack.
///
/// If the parameter is a parameter pack, the type may be a
/// \c PackExpansionType. In the following example, the \c Dims parameter
@@ -1366,7 +1367,7 @@ public:
/// \endcode
bool isParameterPack() const { return ParameterPack; }
- /// \brief Whether this parameter pack is a pack expansion.
+ /// Whether this parameter pack is a pack expansion.
///
/// A non-type template parameter pack is a pack expansion if its type
/// contains an unexpanded parameter pack. In this case, we will have
@@ -1375,7 +1376,7 @@ public:
return ParameterPack && getType()->getAs<PackExpansionType>();
}
- /// \brief Whether this parameter is a non-type template parameter pack
+ /// Whether this parameter is a non-type template parameter pack
/// that has a known list of different types at different positions.
///
/// A parameter pack is an expanded parameter pack when the original
@@ -1401,14 +1402,14 @@ public:
/// return the expansion types.
bool isExpandedParameterPack() const { return ExpandedParameterPack; }
- /// \brief Retrieves the number of expansion types in an expanded parameter
+ /// Retrieves the number of expansion types in an expanded parameter
/// pack.
unsigned getNumExpansionTypes() const {
assert(ExpandedParameterPack && "Not an expansion parameter pack");
return NumExpandedTypes;
}
- /// \brief Retrieve a particular expansion type within an expanded parameter
+ /// Retrieve a particular expansion type within an expanded parameter
/// pack.
QualType getExpansionType(unsigned I) const {
assert(I < NumExpandedTypes && "Out-of-range expansion type index");
@@ -1417,7 +1418,7 @@ public:
return TypesAndInfos[I].first;
}
- /// \brief Retrieve a particular expansion type source info within an
+ /// Retrieve a particular expansion type source info within an
/// expanded parameter pack.
TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
assert(I < NumExpandedTypes && "Out-of-range expansion type index");
@@ -1443,20 +1444,20 @@ class TemplateTemplateParmDecl final
protected TemplateParmPosition,
private llvm::TrailingObjects<TemplateTemplateParmDecl,
TemplateParameterList *> {
- /// \brief The default template argument, if any.
+ /// The default template argument, if any.
using DefArgStorage =
DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *>;
DefArgStorage DefaultArgument;
- /// \brief Whether this parameter is a parameter pack.
+ /// Whether this parameter is a parameter pack.
bool ParameterPack;
- /// \brief Whether this template template parameter is an "expanded"
+ /// Whether this template template parameter is an "expanded"
/// parameter pack, meaning that it is a pack expansion and we
/// already know the set of template parameters that expansion expands to.
bool ExpandedParameterPack = false;
- /// \brief The number of parameters in an expanded parameter pack.
+ /// The number of parameters in an expanded parameter pack.
unsigned NumExpandedParams = 0;
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
@@ -1501,7 +1502,7 @@ public:
using TemplateParmPosition::setPosition;
using TemplateParmPosition::getIndex;
- /// \brief Whether this template template parameter is a template
+ /// Whether this template template parameter is a template
/// parameter pack.
///
/// \code
@@ -1509,7 +1510,7 @@ public:
/// \endcode
bool isParameterPack() const { return ParameterPack; }
- /// \brief Whether this parameter pack is a pack expansion.
+ /// Whether this parameter pack is a pack expansion.
///
/// A template template parameter pack is a pack expansion if its template
/// parameter list contains an unexpanded parameter pack.
@@ -1518,7 +1519,7 @@ public:
getTemplateParameters()->containsUnexpandedParameterPack();
}
- /// \brief Whether this parameter is a template template parameter pack that
+ /// Whether this parameter is a template template parameter pack that
/// has a known list of different template parameter lists at different
/// positions.
///
@@ -1538,14 +1539,14 @@ public:
/// parameter pack.
bool isExpandedParameterPack() const { return ExpandedParameterPack; }
- /// \brief Retrieves the number of expansion template parameters in
+ /// Retrieves the number of expansion template parameters in
/// an expanded parameter pack.
unsigned getNumExpansionTemplateParameters() const {
assert(ExpandedParameterPack && "Not an expansion parameter pack");
return NumExpandedParams;
}
- /// \brief Retrieve a particular expansion type within an expanded parameter
+ /// Retrieve a particular expansion type within an expanded parameter
/// pack.
TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
assert(I < NumExpandedParams && "Out-of-range expansion type index");
@@ -1554,26 +1555,26 @@ public:
const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
- /// \brief Determine whether this template parameter has a default
+ /// Determine whether this template parameter has a default
/// argument.
bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
- /// \brief Retrieve the default argument, if any.
+ /// Retrieve the default argument, if any.
const TemplateArgumentLoc &getDefaultArgument() const {
static const TemplateArgumentLoc None;
return DefaultArgument.isSet() ? *DefaultArgument.get() : None;
}
- /// \brief Retrieve the location of the default argument, if any.
+ /// Retrieve the location of the default argument, if any.
SourceLocation getDefaultArgumentLoc() const;
- /// \brief Determines whether the default argument was inherited
+ /// Determines whether the default argument was inherited
/// from a previous declaration of this template.
bool defaultArgumentWasInherited() const {
return DefaultArgument.isInherited();
}
- /// \brief Set the default argument for this template parameter, and
+ /// Set the default argument for this template parameter, and
/// whether that default argument was inherited from another
/// declaration.
void setDefaultArgument(const ASTContext &C,
@@ -1583,7 +1584,7 @@ public:
DefaultArgument.setInherited(C, Prev);
}
- /// \brief Removes the default argument of this template parameter.
+ /// Removes the default argument of this template parameter.
void removeDefaultArgument() { DefaultArgument.clear(); }
SourceRange getSourceRange() const override LLVM_READONLY {
@@ -1598,7 +1599,7 @@ public:
static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
};
-/// \brief Represents the builtin template declaration which is used to
+/// Represents the builtin template declaration which is used to
/// implement __make_integer_seq and other builtin templates. It serves
/// no real purpose beyond existing as a place to hold template parameters.
class BuiltinTemplateDecl : public TemplateDecl {
@@ -1621,13 +1622,13 @@ public:
}
SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange();
+ return {};
}
BuiltinTemplateKind getBuiltinTemplateKind() const { return BTK; }
};
-/// \brief Represents a class template specialization, which refers to
+/// Represents a class template specialization, which refers to
/// a class template with a given set of template arguments.
///
/// Class template specializations represent both explicit
@@ -1642,48 +1643,48 @@ public:
/// \endcode
class ClassTemplateSpecializationDecl
: public CXXRecordDecl, public llvm::FoldingSetNode {
- /// \brief Structure that stores information about a class template
+ /// Structure that stores information about a class template
/// specialization that was instantiated from a class template partial
/// specialization.
struct SpecializedPartialSpecialization {
- /// \brief The class template partial specialization from which this
+ /// The class template partial specialization from which this
/// class template specialization was instantiated.
ClassTemplatePartialSpecializationDecl *PartialSpecialization;
- /// \brief The template argument list deduced for the class template
+ /// The template argument list deduced for the class template
/// partial specialization itself.
const TemplateArgumentList *TemplateArgs;
};
- /// \brief The template that this specialization specializes
+ /// The template that this specialization specializes
llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
SpecializedTemplate;
- /// \brief Further info for explicit template specialization/instantiation.
+ /// Further info for explicit template specialization/instantiation.
struct ExplicitSpecializationInfo {
- /// \brief The type-as-written.
+ /// The type-as-written.
TypeSourceInfo *TypeAsWritten = nullptr;
- /// \brief The location of the extern keyword.
+ /// The location of the extern keyword.
SourceLocation ExternLoc;
- /// \brief The location of the template keyword.
+ /// The location of the template keyword.
SourceLocation TemplateKeywordLoc;
ExplicitSpecializationInfo() = default;
};
- /// \brief Further info for explicit template specialization/instantiation.
+ /// Further info for explicit template specialization/instantiation.
/// Does not apply to implicit specializations.
ExplicitSpecializationInfo *ExplicitInfo = nullptr;
- /// \brief The template arguments used to describe this specialization.
+ /// The template arguments used to describe this specialization.
const TemplateArgumentList *TemplateArgs;
- /// \brief The point where this template was instantiated (if any)
+ /// The point where this template was instantiated (if any)
SourceLocation PointOfInstantiation;
- /// \brief The kind of specialization this declaration refers to.
+ /// The kind of specialization this declaration refers to.
/// Really a value of type TemplateSpecializationKind.
unsigned SpecializationKind : 3;
@@ -1719,26 +1720,20 @@ public:
// 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();
- while (!isa<ClassTemplateSpecializationDecl>(Recent)) {
- // FIXME: Does injected class name need to be in the redeclarations chain?
- assert(Recent->isInjectedClassName() && Recent->getPreviousDecl());
- Recent = Recent->getPreviousDecl();
- }
- return cast<ClassTemplateSpecializationDecl>(Recent);
+ return cast<ClassTemplateSpecializationDecl>(
+ getMostRecentNonInjectedDecl());
}
- /// \brief Retrieve the template that this specialization specializes.
+ /// Retrieve the template that this specialization specializes.
ClassTemplateDecl *getSpecializedTemplate() const;
- /// \brief Retrieve the template arguments of the class template
+ /// Retrieve the template arguments of the class template
/// specialization.
const TemplateArgumentList &getTemplateArgs() const {
return *TemplateArgs;
}
- /// \brief Determine the kind of specialization that this
+ /// Determine the kind of specialization that this
/// declaration represents.
TemplateSpecializationKind getSpecializationKind() const {
return static_cast<TemplateSpecializationKind>(SpecializationKind);
@@ -1748,7 +1743,7 @@ public:
return getSpecializationKind() == TSK_ExplicitSpecialization;
}
- /// \brief True if this declaration is an explicit specialization,
+ /// True if this declaration is an explicit specialization,
/// explicit instantiation declaration, or explicit instantiation
/// definition.
bool isExplicitInstantiationOrSpecialization() const {
@@ -1760,7 +1755,7 @@ public:
SpecializationKind = TSK;
}
- /// \brief Get the point of instantiation (if any), or null if none.
+ /// Get the point of instantiation (if any), or null if none.
SourceLocation getPointOfInstantiation() const {
return PointOfInstantiation;
}
@@ -1770,7 +1765,7 @@ public:
PointOfInstantiation = Loc;
}
- /// \brief If this class template specialization is an instantiation of
+ /// If this class template specialization is an instantiation of
/// a template (rather than an explicit specialization), return the
/// class template or class template partial specialization from which it
/// was instantiated.
@@ -1784,19 +1779,19 @@ public:
return getSpecializedTemplateOrPartial();
}
- /// \brief Retrieve the class template or class template partial
+ /// Retrieve the class template or class template partial
/// specialization which was specialized by this.
llvm::PointerUnion<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *>
getSpecializedTemplateOrPartial() const {
- if (SpecializedPartialSpecialization *PartialSpec
- = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
+ if (const auto *PartialSpec =
+ SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
return PartialSpec->PartialSpecialization;
return SpecializedTemplate.get<ClassTemplateDecl*>();
}
- /// \brief Retrieve the set of template arguments that should be used
+ /// Retrieve the set of template arguments that should be used
/// to instantiate members of the class template or class template partial
/// specialization from which this class template specialization was
/// instantiated.
@@ -1808,28 +1803,27 @@ public:
/// deduced template arguments for the class template partial specialization
/// itself.
const TemplateArgumentList &getTemplateInstantiationArgs() const {
- if (SpecializedPartialSpecialization *PartialSpec
- = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
+ if (const auto *PartialSpec =
+ SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
return *PartialSpec->TemplateArgs;
return getTemplateArgs();
}
- /// \brief Note that this class template specialization is actually an
+ /// Note that this class template specialization is actually an
/// instantiation of the given class template partial specialization whose
/// template arguments have been deduced.
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
const TemplateArgumentList *TemplateArgs) {
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
"Already set to a class template partial specialization!");
- SpecializedPartialSpecialization *PS
- = new (getASTContext()) SpecializedPartialSpecialization();
+ auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
PS->PartialSpecialization = PartialSpec;
PS->TemplateArgs = TemplateArgs;
SpecializedTemplate = PS;
}
- /// \brief Note that this class template specialization is an instantiation
+ /// Note that this class template specialization is an instantiation
/// of the given class template.
void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
@@ -1837,7 +1831,7 @@ public:
SpecializedTemplate = TemplDecl;
}
- /// \brief Sets the type of this specialization as it was written by
+ /// Sets the type of this specialization as it was written by
/// the user. This will be a class template specialization type.
void setTypeAsWritten(TypeSourceInfo *T) {
if (!ExplicitInfo)
@@ -1845,32 +1839,32 @@ public:
ExplicitInfo->TypeAsWritten = T;
}
- /// \brief Gets the type of this specialization as it was written by
+ /// 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 : nullptr;
}
- /// \brief Gets the location of the extern keyword, if present.
+ /// Gets the location of the extern keyword, if present.
SourceLocation getExternLoc() const {
return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
}
- /// \brief Sets the location of the extern keyword.
+ /// Sets the location of the extern keyword.
void setExternLoc(SourceLocation Loc) {
if (!ExplicitInfo)
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
ExplicitInfo->ExternLoc = Loc;
}
- /// \brief Sets the location of the template keyword.
+ /// Sets the location of the template keyword.
void setTemplateKeywordLoc(SourceLocation Loc) {
if (!ExplicitInfo)
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
ExplicitInfo->TemplateKeywordLoc = Loc;
}
- /// \brief Gets the location of the template keyword, if present.
+ /// Gets the location of the template keyword, if present.
SourceLocation getTemplateKeywordLoc() const {
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
}
@@ -1899,14 +1893,14 @@ public:
class ClassTemplatePartialSpecializationDecl
: public ClassTemplateSpecializationDecl {
- /// \brief The list of template parameters
+ /// The list of template parameters
TemplateParameterList* TemplateParams = nullptr;
- /// \brief The source info for the template arguments as written.
+ /// The source info for the template arguments as written.
/// FIXME: redundant with TypeAsWritten?
const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
- /// \brief The class template partial specialization from which this
+ /// The class template partial specialization from which this
/// class template partial specialization was instantiated.
///
/// The boolean value will be true to indicate that this class template
@@ -1963,7 +1957,7 @@ public:
return ArgsAsWritten;
}
- /// \brief Retrieve the member class template partial specialization from
+ /// Retrieve the member class template partial specialization from
/// which this particular class template partial specialization was
/// instantiated.
///
@@ -1984,7 +1978,7 @@ public:
/// \c Outer<float>::Inner<U*>, this function would return
/// \c Outer<T>::Inner<U*>.
ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
- const ClassTemplatePartialSpecializationDecl *First =
+ const auto *First =
cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
return First->InstantiatedFromMember.getPointer();
}
@@ -1995,12 +1989,11 @@ public:
void setInstantiatedFromMember(
ClassTemplatePartialSpecializationDecl *PartialSpec) {
- ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
+ auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
First->InstantiatedFromMember.setPointer(PartialSpec);
}
- /// \brief Determines whether this class template partial specialization
+ /// Determines whether this class template partial specialization
/// template was a specialization of a member partial specialization.
///
/// In the following example, the member template partial specialization
@@ -2017,15 +2010,14 @@ public:
/// struct X<int>::Inner<T*> { /* ... */ };
/// \endcode
bool isMemberSpecialization() {
- ClassTemplatePartialSpecializationDecl *First =
+ const auto *First =
cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
return First->InstantiatedFromMember.getInt();
}
- /// \brief Note that this member template is a specialization.
+ /// Note that this member template is a specialization.
void setMemberSpecialization() {
- ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
+ auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
assert(First->InstantiatedFromMember.getPointer() &&
"Only member templates can be member template specializations");
return First->InstantiatedFromMember.setInt(true);
@@ -2052,29 +2044,29 @@ public:
/// Declaration of a class template.
class ClassTemplateDecl : public RedeclarableTemplateDecl {
protected:
- /// \brief Data that is common to all of the declarations of a given
+ /// Data that is common to all of the declarations of a given
/// class template.
struct Common : CommonBase {
- /// \brief The class template specializations for this class
+ /// The class template specializations for this class
/// template, including explicit specializations and instantiations.
llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
- /// \brief The class template partial specializations for this class
+ /// The class template partial specializations for this class
/// template.
llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
PartialSpecializations;
- /// \brief The injected-class-name type for this class template.
+ /// The injected-class-name type for this class template.
QualType InjectedClassNameType;
Common() = default;
};
- /// \brief Retrieve the set of specializations of this class template.
+ /// Retrieve the set of specializations of this class template.
llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
getSpecializations() const;
- /// \brief Retrieve the set of partial specializations of this class
+ /// Retrieve the set of partial specializations of this class
/// template.
llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations();
@@ -2100,22 +2092,22 @@ public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
- /// \brief Load any lazily-loaded specializations from the external source.
+ /// Load any lazily-loaded specializations from the external source.
void LoadLazySpecializations() const;
- /// \brief Get the underlying class declarations of the template.
+ /// Get the underlying class declarations of the template.
CXXRecordDecl *getTemplatedDecl() const {
return static_cast<CXXRecordDecl *>(TemplatedDecl);
}
- /// \brief Returns whether this template declaration defines the primary
+ /// Returns whether this template declaration defines the primary
/// class pattern.
bool isThisDeclarationADefinition() const {
return getTemplatedDecl()->isThisDeclarationADefinition();
}
// FIXME: remove default argument for AssociatedConstraints
- /// \brief Create a class template node.
+ /// Create a class template node.
static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName Name,
@@ -2123,15 +2115,15 @@ public:
NamedDecl *Decl,
Expr *AssociatedConstraints = nullptr);
- /// \brief Create an empty class template node.
+ /// Create an empty class template node.
static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- /// \brief Return the specialization with the provided arguments if it exists,
+ /// Return the specialization with the provided arguments if it exists,
/// otherwise return the insertion point.
ClassTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
- /// \brief Insert the specified specialization knowing that it is not already
+ /// Insert the specified specialization knowing that it is not already
/// in. InsertPos must be obtained from findSpecialization.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
@@ -2144,7 +2136,7 @@ public:
RedeclarableTemplateDecl::getCanonicalDecl());
}
- /// \brief Retrieve the previous declaration of this class template, or
+ /// Retrieve the previous declaration of this class template, or
/// nullptr if no such declaration exists.
ClassTemplateDecl *getPreviousDecl() {
return cast_or_null<ClassTemplateDecl>(
@@ -2169,21 +2161,21 @@ public:
RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
}
- /// \brief Return the partial specialization with the provided arguments if it
+ /// Return the partial specialization with the provided arguments if it
/// exists, otherwise return the insertion point.
ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
- /// \brief Insert the specified partial specialization knowing that it is not
+ /// Insert the specified partial specialization knowing that it is not
/// already in. InsertPos must be obtained from findPartialSpecialization.
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
void *InsertPos);
- /// \brief Retrieve the partial specializations as an ordered list.
+ /// Retrieve the partial specializations as an ordered list.
void getPartialSpecializations(
SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
- /// \brief Find a class template partial specialization with the given
+ /// Find a class template partial specialization with the given
/// type T.
///
/// \param T a dependent type that names a specialization of this class
@@ -2193,7 +2185,7 @@ public:
/// the type \p T, or nullptr if no such partial specialization exists.
ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
- /// \brief Find a class template partial specialization which was instantiated
+ /// Find a class template partial specialization which was instantiated
/// from the given member partial specialization.
///
/// \param D a member class template partial specialization.
@@ -2205,7 +2197,7 @@ public:
findPartialSpecInstantiatedFromMember(
ClassTemplatePartialSpecializationDecl *D);
- /// \brief Retrieve the template specialization type of the
+ /// Retrieve the template specialization type of the
/// injected-class-name for this class template.
///
/// The injected-class-name for a class template \c X is \c
@@ -2241,7 +2233,7 @@ public:
static bool classofKind(Kind K) { return K == ClassTemplate; }
};
-/// \brief Declaration of a friend template.
+/// Declaration of a friend template.
///
/// For example:
/// \code
@@ -2305,7 +2297,7 @@ public:
return Friend.dyn_cast<NamedDecl*>();
}
- /// \brief Retrieves the location of the 'friend' keyword.
+ /// Retrieves the location of the 'friend' keyword.
SourceLocation getFriendLoc() const {
return FriendLoc;
}
@@ -2324,7 +2316,7 @@ public:
static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
};
-/// \brief Declaration of an alias template.
+/// Declaration of an alias template.
///
/// For example:
/// \code
@@ -2365,7 +2357,7 @@ public:
RedeclarableTemplateDecl::getCanonicalDecl());
}
- /// \brief Retrieve the previous declaration of this function template, or
+ /// Retrieve the previous declaration of this function template, or
/// nullptr if no such declaration exists.
TypeAliasTemplateDecl *getPreviousDecl() {
return cast_or_null<TypeAliasTemplateDecl>(
@@ -2382,14 +2374,14 @@ public:
RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
}
- /// \brief Create a function template node.
+ /// Create a function template node.
static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl);
- /// \brief Create an empty alias template node.
+ /// Create an empty alias template node.
static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
// Implement isa/cast/dyncast support
@@ -2397,7 +2389,7 @@ public:
static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
};
-/// \brief Declaration of a function specialization at template class scope.
+/// Declaration of a function specialization at template class scope.
///
/// This is a non-standard extension needed to support MSVC.
///
@@ -2463,7 +2455,7 @@ public:
inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
: Function(FTD) {}
-/// \brief Represents a variable template specialization, which refers to
+/// Represents a variable template specialization, which refers to
/// a variable template with a given set of template arguments.
///
/// Variable template specializations represent both explicit
@@ -2479,53 +2471,53 @@ inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
class VarTemplateSpecializationDecl : public VarDecl,
public llvm::FoldingSetNode {
- /// \brief Structure that stores information about a variable template
+ /// Structure that stores information about a variable template
/// specialization that was instantiated from a variable template partial
/// specialization.
struct SpecializedPartialSpecialization {
- /// \brief The variable template partial specialization from which this
+ /// The variable template partial specialization from which this
/// variable template specialization was instantiated.
VarTemplatePartialSpecializationDecl *PartialSpecialization;
- /// \brief The template argument list deduced for the variable template
+ /// The template argument list deduced for the variable template
/// partial specialization itself.
const TemplateArgumentList *TemplateArgs;
};
- /// \brief The template that this specialization specializes.
+ /// The template that this specialization specializes.
llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
SpecializedTemplate;
- /// \brief Further info for explicit template specialization/instantiation.
+ /// Further info for explicit template specialization/instantiation.
struct ExplicitSpecializationInfo {
- /// \brief The type-as-written.
+ /// The type-as-written.
TypeSourceInfo *TypeAsWritten = nullptr;
- /// \brief The location of the extern keyword.
+ /// The location of the extern keyword.
SourceLocation ExternLoc;
- /// \brief The location of the template keyword.
+ /// The location of the template keyword.
SourceLocation TemplateKeywordLoc;
ExplicitSpecializationInfo() = default;
};
- /// \brief Further info for explicit template specialization/instantiation.
+ /// Further info for explicit template specialization/instantiation.
/// Does not apply to implicit specializations.
ExplicitSpecializationInfo *ExplicitInfo = nullptr;
- /// \brief The template arguments used to describe this specialization.
+ /// The template arguments used to describe this specialization.
const TemplateArgumentList *TemplateArgs;
TemplateArgumentListInfo TemplateArgsInfo;
- /// \brief The point where this template was instantiated (if any).
+ /// The point where this template was instantiated (if any).
SourceLocation PointOfInstantiation;
- /// \brief The kind of specialization this declaration refers to.
+ /// The kind of specialization this declaration refers to.
/// Really a value of type TemplateSpecializationKind.
unsigned SpecializationKind : 3;
- /// \brief Whether this declaration is a complete definition of the
+ /// Whether this declaration is a complete definition of the
/// variable template specialization. We can't otherwise tell apart
/// an instantiated declaration from an instantiated definition with
/// no initializer.
@@ -2562,10 +2554,10 @@ public:
return cast<VarTemplateSpecializationDecl>(Recent);
}
- /// \brief Retrieve the template that this specialization specializes.
+ /// Retrieve the template that this specialization specializes.
VarTemplateDecl *getSpecializedTemplate() const;
- /// \brief Retrieve the template arguments of the variable template
+ /// Retrieve the template arguments of the variable template
/// specialization.
const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
@@ -2576,7 +2568,7 @@ public:
return TemplateArgsInfo;
}
- /// \brief Determine the kind of specialization that this
+ /// Determine the kind of specialization that this
/// declaration represents.
TemplateSpecializationKind getSpecializationKind() const {
return static_cast<TemplateSpecializationKind>(SpecializationKind);
@@ -2586,7 +2578,7 @@ public:
return getSpecializationKind() == TSK_ExplicitSpecialization;
}
- /// \brief True if this declaration is an explicit specialization,
+ /// True if this declaration is an explicit specialization,
/// explicit instantiation declaration, or explicit instantiation
/// definition.
bool isExplicitInstantiationOrSpecialization() const {
@@ -2598,7 +2590,7 @@ public:
SpecializationKind = TSK;
}
- /// \brief Get the point of instantiation (if any), or null if none.
+ /// Get the point of instantiation (if any), or null if none.
SourceLocation getPointOfInstantiation() const {
return PointOfInstantiation;
}
@@ -2610,7 +2602,7 @@ public:
void setCompleteDefinition() { IsCompleteDefinition = true; }
- /// \brief If this variable template specialization is an instantiation of
+ /// If this variable template specialization is an instantiation of
/// a template (rather than an explicit specialization), return the
/// variable template or variable template partial specialization from which
/// it was instantiated.
@@ -2623,18 +2615,18 @@ public:
return getSpecializedTemplateOrPartial();
}
- /// \brief Retrieve the variable template or variable template partial
+ /// Retrieve the variable template or variable template partial
/// specialization which was specialized by this.
llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
getSpecializedTemplateOrPartial() const {
- if (SpecializedPartialSpecialization *PartialSpec =
+ if (const auto *PartialSpec =
SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
return PartialSpec->PartialSpecialization;
return SpecializedTemplate.get<VarTemplateDecl *>();
}
- /// \brief Retrieve the set of template arguments that should be used
+ /// Retrieve the set of template arguments that should be used
/// to instantiate the initializer of the variable template or variable
/// template partial specialization from which this variable template
/// specialization was instantiated.
@@ -2646,28 +2638,27 @@ public:
/// return deduced template arguments for the variable template partial
/// specialization itself.
const TemplateArgumentList &getTemplateInstantiationArgs() const {
- if (SpecializedPartialSpecialization *PartialSpec =
+ if (const auto *PartialSpec =
SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
return *PartialSpec->TemplateArgs;
return getTemplateArgs();
}
- /// \brief Note that this variable template specialization is actually an
+ /// Note that this variable template specialization is actually an
/// instantiation of the given variable template partial specialization whose
/// template arguments have been deduced.
void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
const TemplateArgumentList *TemplateArgs) {
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
"Already set to a variable template partial specialization!");
- SpecializedPartialSpecialization *PS =
- new (getASTContext()) SpecializedPartialSpecialization();
+ auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
PS->PartialSpecialization = PartialSpec;
PS->TemplateArgs = TemplateArgs;
SpecializedTemplate = PS;
}
- /// \brief Note that this variable template specialization is an instantiation
+ /// Note that this variable template specialization is an instantiation
/// of the given variable template.
void setInstantiationOf(VarTemplateDecl *TemplDecl) {
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
@@ -2675,7 +2666,7 @@ public:
SpecializedTemplate = TemplDecl;
}
- /// \brief Sets the type of this specialization as it was written by
+ /// Sets the type of this specialization as it was written by
/// the user.
void setTypeAsWritten(TypeSourceInfo *T) {
if (!ExplicitInfo)
@@ -2683,32 +2674,32 @@ public:
ExplicitInfo->TypeAsWritten = T;
}
- /// \brief Gets the type of this specialization as it was written by
+ /// 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 : nullptr;
}
- /// \brief Gets the location of the extern keyword, if present.
+ /// Gets the location of the extern keyword, if present.
SourceLocation getExternLoc() const {
return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
}
- /// \brief Sets the location of the extern keyword.
+ /// Sets the location of the extern keyword.
void setExternLoc(SourceLocation Loc) {
if (!ExplicitInfo)
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
ExplicitInfo->ExternLoc = Loc;
}
- /// \brief Sets the location of the template keyword.
+ /// Sets the location of the template keyword.
void setTemplateKeywordLoc(SourceLocation Loc) {
if (!ExplicitInfo)
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
ExplicitInfo->TemplateKeywordLoc = Loc;
}
- /// \brief Gets the location of the template keyword, if present.
+ /// Gets the location of the template keyword, if present.
SourceLocation getTemplateKeywordLoc() const {
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
}
@@ -2735,14 +2726,14 @@ public:
class VarTemplatePartialSpecializationDecl
: public VarTemplateSpecializationDecl {
- /// \brief The list of template parameters
+ /// The list of template parameters
TemplateParameterList *TemplateParams = nullptr;
- /// \brief The source info for the template arguments as written.
+ /// The source info for the template arguments as written.
/// FIXME: redundant with TypeAsWritten?
const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
- /// \brief The variable template partial specialization from which this
+ /// The variable template partial specialization from which this
/// variable template partial specialization was instantiated.
///
/// The boolean value will be true to indicate that this variable template
@@ -2794,7 +2785,7 @@ public:
return ArgsAsWritten;
}
- /// \brief Retrieve the member variable template partial specialization from
+ /// Retrieve the member variable template partial specialization from
/// which this particular variable template partial specialization was
/// instantiated.
///
@@ -2815,19 +2806,18 @@ public:
/// \c Outer<float>::Inner<U*>, this function would return
/// \c Outer<T>::Inner<U*>.
VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
- const VarTemplatePartialSpecializationDecl *First =
+ const auto *First =
cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
return First->InstantiatedFromMember.getPointer();
}
void
setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
- VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
+ auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
First->InstantiatedFromMember.setPointer(PartialSpec);
}
- /// \brief Determines whether this variable template partial specialization
+ /// Determines whether this variable template partial specialization
/// was a specialization of a member partial specialization.
///
/// In the following example, the member template partial specialization
@@ -2844,15 +2834,14 @@ public:
/// U* X<int>::Inner<T*> = (T*)(0) + 1;
/// \endcode
bool isMemberSpecialization() {
- VarTemplatePartialSpecializationDecl *First =
+ const auto *First =
cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
return First->InstantiatedFromMember.getInt();
}
- /// \brief Note that this member template is a specialization.
+ /// Note that this member template is a specialization.
void setMemberSpecialization() {
- VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
+ auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
assert(First->InstantiatedFromMember.getPointer() &&
"Only member templates can be member template specializations");
return First->InstantiatedFromMember.setInt(true);
@@ -2868,14 +2857,14 @@ public:
/// Declaration of a variable template.
class VarTemplateDecl : public RedeclarableTemplateDecl {
protected:
- /// \brief Data that is common to all of the declarations of a given
+ /// Data that is common to all of the declarations of a given
/// variable template.
struct Common : CommonBase {
- /// \brief The variable template specializations for this variable
+ /// The variable template specializations for this variable
/// template, including explicit specializations and instantiations.
llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
- /// \brief The variable template partial specializations for this variable
+ /// The variable template partial specializations for this variable
/// template.
llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
PartialSpecializations;
@@ -2883,11 +2872,11 @@ protected:
Common() = default;
};
- /// \brief Retrieve the set of specializations of this variable template.
+ /// Retrieve the set of specializations of this variable template.
llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
getSpecializations() const;
- /// \brief Retrieve the set of partial specializations of this class
+ /// Retrieve the set of partial specializations of this class
/// template.
llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
getPartialSpecializations();
@@ -2907,15 +2896,15 @@ public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
- /// \brief Load any lazily-loaded specializations from the external source.
+ /// Load any lazily-loaded specializations from the external source.
void LoadLazySpecializations() const;
- /// \brief Get the underlying variable declarations of the template.
+ /// Get the underlying variable declarations of the template.
VarDecl *getTemplatedDecl() const {
return static_cast<VarDecl *>(TemplatedDecl);
}
- /// \brief Returns whether this template declaration defines the primary
+ /// Returns whether this template declaration defines the primary
/// variable pattern.
bool isThisDeclarationADefinition() const {
return getTemplatedDecl()->isThisDeclarationADefinition();
@@ -2923,21 +2912,21 @@ public:
VarTemplateDecl *getDefinition();
- /// \brief Create a variable template node.
+ /// Create a variable template node.
static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params,
VarDecl *Decl);
- /// \brief Create an empty variable template node.
+ /// Create an empty variable template node.
static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- /// \brief Return the specialization with the provided arguments if it exists,
+ /// Return the specialization with the provided arguments if it exists,
/// otherwise return the insertion point.
VarTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
- /// \brief Insert the specified specialization knowing that it is not already
+ /// Insert the specified specialization knowing that it is not already
/// in. InsertPos must be obtained from findSpecialization.
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
@@ -2948,7 +2937,7 @@ public:
return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
}
- /// \brief Retrieve the previous declaration of this variable template, or
+ /// Retrieve the previous declaration of this variable template, or
/// nullptr if no such declaration exists.
VarTemplateDecl *getPreviousDecl() {
return cast_or_null<VarTemplateDecl>(
@@ -2973,21 +2962,21 @@ public:
RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
}
- /// \brief Return the partial specialization with the provided arguments if it
+ /// Return the partial specialization with the provided arguments if it
/// exists, otherwise return the insertion point.
VarTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
- /// \brief Insert the specified partial specialization knowing that it is not
+ /// Insert the specified partial specialization knowing that it is not
/// already in. InsertPos must be obtained from findPartialSpecialization.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D,
void *InsertPos);
- /// \brief Retrieve the partial specializations as an ordered list.
+ /// Retrieve the partial specializations as an ordered list.
void getPartialSpecializations(
SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS);
- /// \brief Find a variable template partial specialization which was
+ /// Find a variable template partial specialization which was
/// instantiated
/// from the given member partial specialization.
///
@@ -3021,11 +3010,11 @@ public:
};
inline NamedDecl *getAsNamedDecl(TemplateParameter P) {
- if (auto *PD = P.dyn_cast<TemplateTypeParmDecl*>())
+ if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
return PD;
- if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl*>())
+ if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
return PD;
- return P.get<TemplateTemplateParmDecl*>();
+ return P.get<TemplateTemplateParmDecl *>();
}
inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h
index 3ff274bd6a7a1..520a4a10bfe10 100644
--- a/include/clang/AST/DeclVisitor.h
+++ b/include/clang/AST/DeclVisitor.h
@@ -30,7 +30,7 @@ namespace declvisitor {
template <typename T> struct make_ptr { using type = T *; };
template <typename T> struct make_const_ptr { using type = const T *; };
-/// \brief A simple visitor class that helps create declaration visitors.
+/// A simple visitor class that helps create declaration visitors.
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
class Base {
public:
@@ -62,7 +62,7 @@ public:
} // namespace declvisitor
-/// \brief A simple visitor class that helps create declaration visitors.
+/// A simple visitor class that helps create declaration visitors.
///
/// This class does not preserve constness of Decl pointers (see also
/// ConstDeclVisitor).
@@ -70,7 +70,7 @@ template<typename ImplClass, typename RetTy = void>
class DeclVisitor
: public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {};
-/// \brief A simple visitor class that helps create declaration visitors.
+/// A simple visitor class that helps create declaration visitors.
///
/// This class preserves constness of Decl pointers (see also DeclVisitor).
template<typename ImplClass, typename RetTy = void>
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 467b02c52b0c9..9d3dad6bbd9d2 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -194,7 +194,7 @@ public:
(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
}
- /// \brief Evaluates true when this declaration name is empty.
+ /// Evaluates true when this declaration name is empty.
bool isEmpty() const {
return !*this;
}
@@ -211,7 +211,7 @@ public:
/// getNameKind - Determine what kind of name this is.
NameKind getNameKind() const;
- /// \brief Determines whether the name itself is dependent, e.g., because it
+ /// Determines whether the name itself is dependent, e.g., because it
/// involves a C++ type that is itself dependent.
///
/// Note that this does not capture all of the notions of "dependent name",
@@ -541,10 +541,10 @@ public:
LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
}
- /// \brief Determine whether this name involves a template parameter.
+ /// Determine whether this name involves a template parameter.
bool isInstantiationDependent() const;
- /// \brief Determine whether this name contains an unexpanded
+ /// Determine whether this name contains an unexpanded
/// parameter pack.
bool containsUnexpandedParameterPack() const;
diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h
index aad7726f8484d..e00986dbe9c86 100644
--- a/include/clang/AST/EvaluatedExprVisitor.h
+++ b/include/clang/AST/EvaluatedExprVisitor.h
@@ -24,7 +24,7 @@ namespace clang {
class ASTContext;
-/// \brief Given a potentially-evaluated expression, this visitor visits all
+/// Given a potentially-evaluated expression, this visitor visits all
/// of its potentially-evaluated subexpressions, recursively.
template<template <typename> class Ptr, typename ImplClass>
class EvaluatedExprVisitorBase : public StmtVisitorBase<Ptr, ImplClass, void> {
@@ -95,7 +95,7 @@ public:
this->Visit(*I);
}
- /// \brief The basis case walks all of the children of the statement or
+ /// The basis case walks all of the children of the statement or
/// expression, assuming they are all potentially evaluated.
void VisitStmt(PTR(Stmt) S) {
for (auto *SubStmt : S->children())
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index f2770940372fd..7585231e62e5c 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -52,10 +52,10 @@ namespace clang {
class TargetInfo;
class ValueDecl;
-/// \brief A simple array of base specifiers.
+/// A simple array of base specifiers.
typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
-/// \brief An adjustment to be made to the temporary created when emitting a
+/// An adjustment to be made to the temporary created when emitting a
/// reference binding, which accesses a particular subobject of that temporary.
struct SubobjectAdjustment {
enum {
@@ -121,7 +121,7 @@ protected:
setType(T);
}
- /// \brief Construct an empty expression.
+ /// Construct an empty expression.
explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { }
public:
@@ -148,7 +148,7 @@ public:
/// @endcode
bool isValueDependent() const { return ExprBits.ValueDependent; }
- /// \brief Set whether this expression is value-dependent or not.
+ /// Set whether this expression is value-dependent or not.
void setValueDependent(bool VD) {
ExprBits.ValueDependent = VD;
}
@@ -166,12 +166,12 @@ public:
/// @endcode
bool isTypeDependent() const { return ExprBits.TypeDependent; }
- /// \brief Set whether this expression is type-dependent or not.
+ /// Set whether this expression is type-dependent or not.
void setTypeDependent(bool TD) {
ExprBits.TypeDependent = TD;
}
- /// \brief Whether this expression is instantiation-dependent, meaning that
+ /// Whether this expression is instantiation-dependent, meaning that
/// it depends in some way on a template parameter, even if neither its type
/// nor (constant) value can change due to the template instantiation.
///
@@ -192,12 +192,12 @@ public:
return ExprBits.InstantiationDependent;
}
- /// \brief Set whether this expression is instantiation-dependent or not.
+ /// Set whether this expression is instantiation-dependent or not.
void setInstantiationDependent(bool ID) {
ExprBits.InstantiationDependent = ID;
}
- /// \brief Whether this expression contains an unexpanded parameter
+ /// Whether this expression contains an unexpanded parameter
/// pack (for C++11 variadic templates).
///
/// Given the following function template:
@@ -215,7 +215,7 @@ public:
return ExprBits.ContainsUnexpandedParameterPack;
}
- /// \brief Set the bit that describes whether this expression
+ /// Set the bit that describes whether this expression
/// contains an unexpanded parameter pack.
void setContainsUnexpandedParameterPack(bool PP = true) {
ExprBits.ContainsUnexpandedParameterPack = PP;
@@ -297,11 +297,11 @@ public:
isModifiableLvalueResult
isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = nullptr) const;
- /// \brief The return type of classify(). Represents the C++11 expression
+ /// The return type of classify(). Represents the C++11 expression
/// taxonomy.
class Classification {
public:
- /// \brief The various classification results. Most of these mean prvalue.
+ /// The various classification results. Most of these mean prvalue.
enum Kinds {
CL_LValue,
CL_XValue,
@@ -316,7 +316,7 @@ public:
CL_ObjCMessageRValue, // ObjC message is an rvalue
CL_PRValue // A prvalue for any other reason, of any other type
};
- /// \brief The results of modification testing.
+ /// The results of modification testing.
enum ModifiableType {
CM_Untested, // testModifiable was false.
CM_Modifiable,
@@ -356,13 +356,13 @@ public:
bool isRValue() const { return Kind >= CL_XValue; }
bool isModifiable() const { return getModifiable() == CM_Modifiable; }
- /// \brief Create a simple, modifiably lvalue
+ /// Create a simple, modifiably lvalue
static Classification makeSimpleLValue() {
return Classification(CL_LValue, CM_Modifiable);
}
};
- /// \brief Classify - Classify this expression according to the C++11
+ /// Classify - Classify this expression according to the C++11
/// expression taxonomy.
///
/// C++11 defines ([basic.lval]) a new taxonomy of expressions to replace the
@@ -378,7 +378,7 @@ public:
return ClassifyImpl(Ctx, nullptr);
}
- /// \brief ClassifyModifiable - Classify this expression according to the
+ /// ClassifyModifiable - Classify this expression according to the
/// C++11 expression taxonomy, and see if it is valid on the left side
/// of an assignment.
///
@@ -429,14 +429,14 @@ private:
public:
- /// \brief Returns true if this expression is a gl-value that
+ /// Returns true if this expression is a gl-value that
/// potentially refers to a bit-field.
///
/// In C++, whether a gl-value refers to a bitfield is essentially
/// an aspect of the value-kind type system.
bool refersToBitField() const { return getObjectKind() == OK_BitField; }
- /// \brief If this expression refers to a bit-field, retrieve the
+ /// If this expression refers to a bit-field, retrieve the
/// declaration of that bit-field.
///
/// Note that this returns a non-null pointer in subtly different
@@ -454,26 +454,26 @@ public:
return const_cast<Expr*>(this)->getReferencedDeclOfCallee();
}
- /// \brief If this expression is an l-value for an Objective C
+ /// If this expression is an l-value for an Objective C
/// property, find the underlying property reference expression.
const ObjCPropertyRefExpr *getObjCProperty() const;
- /// \brief Check if this expression is the ObjC 'self' implicit parameter.
+ /// Check if this expression is the ObjC 'self' implicit parameter.
bool isObjCSelfExpr() const;
- /// \brief Returns whether this expression refers to a vector element.
+ /// Returns whether this expression refers to a vector element.
bool refersToVectorElement() const;
- /// \brief Returns whether this expression refers to a global register
+ /// Returns whether this expression refers to a global register
/// variable.
bool refersToGlobalRegisterVar() const;
- /// \brief Returns whether this expression has a placeholder type.
+ /// Returns whether this expression has a placeholder type.
bool hasPlaceholderType() const {
return getType()->isPlaceholderType();
}
- /// \brief Returns whether this expression has a specific placeholder type.
+ /// Returns whether this expression has a specific placeholder type.
bool hasPlaceholderType(BuiltinType::Kind K) const {
assert(BuiltinType::isPlaceholderTypeKind(K));
if (const BuiltinType *BT = dyn_cast<BuiltinType>(getType()))
@@ -539,11 +539,11 @@ public:
/// EvalStatus is a struct with detailed info about an evaluation in progress.
struct EvalStatus {
- /// \brief Whether the evaluated expression has side effects.
+ /// Whether the evaluated expression has side effects.
/// For example, (f() && 0) can be folded, but it still has side effects.
bool HasSideEffects;
- /// \brief Whether the evaluation hit undefined behavior.
+ /// Whether the evaluation hit undefined behavior.
/// For example, 1.0 / 0.0 can be folded to Inf, but has undefined behavior.
/// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB.
bool HasUndefinedBehavior;
@@ -586,7 +586,7 @@ public:
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const;
/// EvaluateAsBooleanCondition - Return true if this is a constant
- /// which we we can fold and convert to a boolean condition using
+ /// which we can fold and convert to a boolean condition using
/// any crazy technique that we want to, even if the expression has
/// side-effects.
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const;
@@ -625,7 +625,7 @@ public:
bool HasSideEffects(const ASTContext &Ctx,
bool IncludePossibleEffects = true) const;
- /// \brief Determine whether this expression involves a call to any function
+ /// Determine whether this expression involves a call to any function
/// that is not trivial.
bool hasNonTrivialCall(const ASTContext &Ctx) const;
@@ -658,7 +658,14 @@ public:
ArrayRef<const Expr*> Args,
const Expr *This = nullptr) const;
- /// \brief If the current Expr is a pointer, this will try to statically
+ /// Indicates how the constant expression will be used.
+ enum ConstExprUsage { EvaluateForCodeGen, EvaluateForMangling };
+
+ /// Evaluate an expression that is required to be a constant expression.
+ bool EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage,
+ const ASTContext &Ctx) const;
+
+ /// If the current Expr is a pointer, this will try to statically
/// determine the number of bytes available where the pointer is pointing.
/// Returns true if all of the above holds and we were able to figure out the
/// size, false otherwise.
@@ -668,40 +675,40 @@ public:
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx,
unsigned Type) const;
- /// \brief Enumeration used to describe the kind of Null pointer constant
+ /// Enumeration used to describe the kind of Null pointer constant
/// returned from \c isNullPointerConstant().
enum NullPointerConstantKind {
- /// \brief Expression is not a Null pointer constant.
+ /// Expression is not a Null pointer constant.
NPCK_NotNull = 0,
- /// \brief Expression is a Null pointer constant built from a zero integer
+ /// Expression is a Null pointer constant built from a zero integer
/// expression that is not a simple, possibly parenthesized, zero literal.
/// C++ Core Issue 903 will classify these expressions as "not pointers"
/// once it is adopted.
/// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#903
NPCK_ZeroExpression,
- /// \brief Expression is a Null pointer constant built from a literal zero.
+ /// Expression is a Null pointer constant built from a literal zero.
NPCK_ZeroLiteral,
- /// \brief Expression is a C++11 nullptr.
+ /// Expression is a C++11 nullptr.
NPCK_CXX11_nullptr,
- /// \brief Expression is a GNU-style __null constant.
+ /// Expression is a GNU-style __null constant.
NPCK_GNUNull
};
- /// \brief Enumeration used to describe how \c isNullPointerConstant()
+ /// Enumeration used to describe how \c isNullPointerConstant()
/// should cope with value-dependent expressions.
enum NullPointerConstantValueDependence {
- /// \brief Specifies that the expression should never be value-dependent.
+ /// Specifies that the expression should never be value-dependent.
NPC_NeverValueDependent = 0,
- /// \brief Specifies that a value-dependent expression of integral or
+ /// Specifies that a value-dependent expression of integral or
/// dependent type should be considered a null pointer constant.
NPC_ValueDependentIsNull,
- /// \brief Specifies that a value-dependent expression should be considered
+ /// Specifies that a value-dependent expression should be considered
/// to never be a null pointer constant.
NPC_ValueDependentIsNotNull
};
@@ -717,10 +724,10 @@ public:
/// write barrier.
bool isOBJCGCCandidate(ASTContext &Ctx) const;
- /// \brief Returns true if this expression is a bound member function.
+ /// Returns true if this expression is a bound member function.
bool isBoundMemberFunction(ASTContext &Ctx) const;
- /// \brief Given an expression of bound-member type, find the type
+ /// Given an expression of bound-member type, find the type
/// of the member. Returns null if this is an *overloaded* bound
/// member expression.
static QualType findBoundMemberType(const Expr *expr);
@@ -788,7 +795,7 @@ public:
return const_cast<Expr*>(this)->ignoreParenBaseCasts();
}
- /// \brief Determine whether this expression is a default function argument.
+ /// Determine whether this expression is a default function argument.
///
/// Default arguments are implicitly generated in the abstract syntax tree
/// by semantic analysis for function calls, object constructions, etc. in
@@ -797,11 +804,11 @@ public:
/// the expression is a default argument.
bool isDefaultArgument() const;
- /// \brief Determine whether the result of this expression is a
+ /// Determine whether the result of this expression is a
/// temporary object of the given class type.
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const;
- /// \brief Whether this expression is an implicit reference to 'this' in C++.
+ /// Whether this expression is an implicit reference to 'this' in C++.
bool isImplicitCXXThis() const;
const Expr *IgnoreImpCasts() const LLVM_READONLY {
@@ -824,7 +831,7 @@ public:
static bool hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs);
- /// \brief For an expression of class type or pointer to class type,
+ /// For an expression of class type or pointer to class type,
/// return the most derived class decl the expression is known to refer to.
///
/// If this expression is a cast, this method looks through it to find the
@@ -833,7 +840,7 @@ public:
/// behavior if the object isn't dynamically of the derived type.
const CXXRecordDecl *getBestDynamicClassType() const;
- /// \brief Get the inner expression that determines the best dynamic class.
+ /// Get the inner expression that determines the best dynamic class.
/// If this is a prvalue, we guarantee that it is of the most-derived type
/// for the object itself.
const Expr *getBestDynamicClassTypeExpr() const;
@@ -883,6 +890,7 @@ public:
(SourceExpr && SourceExpr->isInstantiationDependent()),
false),
SourceExpr(SourceExpr), Loc(Loc) {
+ setIsUnique(false);
}
/// Given an expression which invokes a copy constructor --- i.e. a
@@ -893,7 +901,7 @@ public:
explicit OpaqueValueExpr(EmptyShell Empty)
: Expr(OpaqueValueExprClass, Empty) { }
- /// \brief Retrieve the location of this expression.
+ /// Retrieve the location of this expression.
SourceLocation getLocation() const { return Loc; }
SourceLocation getLocStart() const LLVM_READONLY {
@@ -925,12 +933,20 @@ public:
/// place.
Expr *getSourceExpr() const { return SourceExpr; }
+ void setIsUnique(bool V) {
+ assert((!V || SourceExpr) &&
+ "unique OVEs are expected to have source expressions");
+ OpaqueValueExprBits.IsUnique = V;
+ }
+
+ bool isUnique() const { return OpaqueValueExprBits.IsUnique; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OpaqueValueExprClass;
}
};
-/// \brief A reference to a declared variable, function, enum, etc.
+/// A reference to a declared variable, function, enum, etc.
/// [C99 6.5.1p2]
///
/// This encodes all the information about how a declaration is referenced
@@ -958,13 +974,13 @@ class DeclRefExpr final
private llvm::TrailingObjects<DeclRefExpr, NestedNameSpecifierLoc,
NamedDecl *, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
- /// \brief The declaration that we are referencing.
+ /// The declaration that we are referencing.
ValueDecl *D;
- /// \brief The location of the declaration name itself.
+ /// The location of the declaration name itself.
SourceLocation Loc;
- /// \brief Provides source/type location info for the declaration name
+ /// Provides source/type location info for the declaration name
/// embedded in D.
DeclarationNameLoc DNLoc;
@@ -980,7 +996,7 @@ class DeclRefExpr final
return hasTemplateKWAndArgsInfo() ? 1 : 0;
}
- /// \brief Test whether there is a distinct FoundDecl attached to the end of
+ /// Test whether there is a distinct FoundDecl attached to the end of
/// this DRE.
bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; }
@@ -993,11 +1009,11 @@ class DeclRefExpr final
const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK);
- /// \brief Construct an empty declaration reference expression.
+ /// Construct an empty declaration reference expression.
explicit DeclRefExpr(EmptyShell Empty)
: Expr(DeclRefExprClass, Empty) { }
- /// \brief Computes the type- and value-dependence flags for this
+ /// Computes the type- and value-dependence flags for this
/// declaration reference expression.
void computeDependence(const ASTContext &C);
@@ -1031,7 +1047,7 @@ public:
NamedDecl *FoundD = nullptr,
const TemplateArgumentListInfo *TemplateArgs = nullptr);
- /// \brief Construct an empty declaration reference expression.
+ /// Construct an empty declaration reference expression.
static DeclRefExpr *CreateEmpty(const ASTContext &Context,
bool HasQualifier,
bool HasFoundDecl,
@@ -1051,11 +1067,11 @@ public:
SourceLocation getLocStart() const LLVM_READONLY;
SourceLocation getLocEnd() const LLVM_READONLY;
- /// \brief Determine whether this declaration reference was preceded by a
+ /// Determine whether this declaration reference was preceded by a
/// C++ nested-name-specifier, e.g., \c N::foo.
bool hasQualifier() const { return DeclRefExprBits.HasQualifier; }
- /// \brief If the name was qualified, retrieves the nested-name-specifier
+ /// If the name was qualified, retrieves the nested-name-specifier
/// that precedes the name, with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const {
if (!hasQualifier())
@@ -1063,13 +1079,13 @@ public:
return *getTrailingObjects<NestedNameSpecifierLoc>();
}
- /// \brief If the name was qualified, retrieves the nested-name-specifier
+ /// If the name was qualified, retrieves the nested-name-specifier
/// that precedes the name. Otherwise, returns NULL.
NestedNameSpecifier *getQualifier() const {
return getQualifierLoc().getNestedNameSpecifier();
}
- /// \brief Get the NamedDecl through which this reference occurred.
+ /// Get the NamedDecl through which this reference occurred.
///
/// This Decl may be different from the ValueDecl actually referred to in the
/// presence of using declarations, etc. It always returns non-NULL, and may
@@ -1079,7 +1095,7 @@ public:
return hasFoundDecl() ? *getTrailingObjects<NamedDecl *>() : D;
}
- /// \brief Get the NamedDecl through which this reference occurred.
+ /// Get the NamedDecl through which this reference occurred.
/// See non-const variant.
const NamedDecl *getFoundDecl() const {
return hasFoundDecl() ? *getTrailingObjects<NamedDecl *>() : D;
@@ -1089,36 +1105,36 @@ public:
return DeclRefExprBits.HasTemplateKWAndArgsInfo;
}
- /// \brief Retrieve the location of the template keyword preceding
+ /// Retrieve the location of the template keyword preceding
/// this name, if any.
SourceLocation getTemplateKeywordLoc() const {
if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
}
- /// \brief Retrieve the location of the left angle bracket starting the
+ /// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the name, if any.
SourceLocation getLAngleLoc() const {
if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
}
- /// \brief Retrieve the location of the right angle bracket ending the
+ /// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the name, if any.
SourceLocation getRAngleLoc() const {
if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
}
- /// \brief Determines whether the name in this declaration reference
+ /// Determines whether the name in this declaration reference
/// was preceded by the template keyword.
bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
- /// \brief Determines whether this declaration reference was followed by an
+ /// Determines whether this declaration reference was followed by an
/// explicit template argument list.
bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
- /// \brief Copies the template arguments (if present) into the given
+ /// Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgs())
@@ -1126,7 +1142,7 @@ public:
getTrailingObjects<TemplateArgumentLoc>(), List);
}
- /// \brief Retrieve the template arguments provided as part of this
+ /// Retrieve the template arguments provided as part of this
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
@@ -1135,7 +1151,7 @@ public:
return getTrailingObjects<TemplateArgumentLoc>();
}
- /// \brief Retrieve the number of template arguments provided as part of this
+ /// Retrieve the number of template arguments provided as part of this
/// template-id.
unsigned getNumTemplateArgs() const {
if (!hasExplicitTemplateArgs())
@@ -1148,19 +1164,19 @@ public:
return {getTemplateArgs(), getNumTemplateArgs()};
}
- /// \brief Returns true if this expression refers to a function that
+ /// Returns true if this expression refers to a function that
/// was resolved from an overloaded set having size greater than 1.
bool hadMultipleCandidates() const {
return DeclRefExprBits.HadMultipleCandidates;
}
- /// \brief Sets the flag telling whether this expression refers to
+ /// Sets the flag telling whether this expression refers to
/// a function that was resolved from an overloaded set having size
/// greater than 1.
void setHadMultipleCandidates(bool V = true) {
DeclRefExprBits.HadMultipleCandidates = V;
}
- /// \brief Does this DeclRefExpr refer to an enclosing local or a captured
+ /// Does this DeclRefExpr refer to an enclosing local or a captured
/// variable?
bool refersToEnclosingVariableOrCapture() const {
return DeclRefExprBits.RefersToEnclosingVariableOrCapture;
@@ -1184,17 +1200,18 @@ public:
friend class ASTStmtWriter;
};
-/// \brief [C99 6.4.2.2] - A predefined identifier such as __func__.
+/// [C99 6.4.2.2] - A predefined identifier such as __func__.
class PredefinedExpr : public Expr {
public:
enum IdentType {
Func,
Function,
- LFunction, // Same as Function, but as wide string.
+ LFunction, // Same as Function, but as wide string.
FuncDName,
FuncSig,
+ LFuncSig, // Same as FuncSig, but as as wide string
PrettyFunction,
- /// \brief The same as PrettyFunction, except that the
+ /// The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
PrettyFunctionNoVirtual
};
@@ -1208,7 +1225,7 @@ public:
PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT,
StringLiteral *SL);
- /// \brief Construct an empty predefined expression.
+ /// Construct an empty predefined expression.
explicit PredefinedExpr(EmptyShell Empty)
: Expr(PredefinedExprClass, Empty), Loc(), Type(Func), FnName(nullptr) {}
@@ -1241,7 +1258,7 @@ public:
friend class ASTStmtReader;
};
-/// \brief Used by IntegerLiteral/FloatingLiteral to store the numeric without
+/// Used by IntegerLiteral/FloatingLiteral to store the numeric without
/// leaking memory.
///
/// For large floats/integers, APFloat/APInt will allocate memory from the heap
@@ -1295,7 +1312,7 @@ public:
class IntegerLiteral : public Expr, public APIntStorage {
SourceLocation Loc;
- /// \brief Construct an empty integer literal.
+ /// Construct an empty integer literal.
explicit IntegerLiteral(EmptyShell Empty)
: Expr(IntegerLiteralClass, Empty) { }
@@ -1305,19 +1322,19 @@ public:
IntegerLiteral(const ASTContext &C, const llvm::APInt &V, QualType type,
SourceLocation l);
- /// \brief Returns a new integer literal with value 'V' and type 'type'.
+ /// Returns a new integer literal with value 'V' and type 'type'.
/// \param type - either IntTy, LongTy, LongLongTy, UnsignedIntTy,
/// UnsignedLongTy, or UnsignedLongLongTy which should match the size of V
/// \param V - the value that the returned integer literal contains.
static IntegerLiteral *Create(const ASTContext &C, const llvm::APInt &V,
QualType type, SourceLocation l);
- /// \brief Returns a new empty integer literal.
+ /// Returns a new empty integer literal.
static IntegerLiteral *Create(const ASTContext &C, EmptyShell Empty);
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
- /// \brief Retrieve the location of the literal.
+ /// Retrieve the location of the literal.
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation Location) { Loc = Location; }
@@ -1335,6 +1352,47 @@ public:
}
};
+class FixedPointLiteral : public Expr, public APIntStorage {
+ SourceLocation Loc;
+ unsigned Scale;
+
+ /// \brief Construct an empty integer literal.
+ explicit FixedPointLiteral(EmptyShell Empty)
+ : Expr(FixedPointLiteralClass, Empty) {}
+
+ public:
+ FixedPointLiteral(const ASTContext &C, const llvm::APInt &V, QualType type,
+ SourceLocation l, unsigned Scale);
+
+ // Store the int as is without any bit shifting.
+ static FixedPointLiteral *CreateFromRawInt(const ASTContext &C,
+ const llvm::APInt &V,
+ QualType type, SourceLocation l,
+ unsigned Scale);
+
+ SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+ /// \brief Retrieve the location of the literal.
+ SourceLocation getLocation() const { return Loc; }
+
+ void setLocation(SourceLocation Location) { Loc = Location; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == FixedPointLiteralClass;
+ }
+
+ std::string getValueAsString(unsigned Radix) const;
+
+ // Iterators
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+};
+
class CharacterLiteral : public Expr {
public:
enum CharacterKind {
@@ -1358,7 +1416,7 @@ public:
CharacterLiteralBits.Kind = kind;
}
- /// \brief Construct an empty character literal.
+ /// Construct an empty character literal.
CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { }
SourceLocation getLocation() const { return Loc; }
@@ -1394,7 +1452,7 @@ class FloatingLiteral : public Expr, private APFloatStorage {
FloatingLiteral(const ASTContext &C, const llvm::APFloat &V, bool isexact,
QualType Type, SourceLocation L);
- /// \brief Construct an empty floating-point literal.
+ /// Construct an empty floating-point literal.
explicit FloatingLiteral(const ASTContext &C, EmptyShell Empty);
public:
@@ -1468,7 +1526,7 @@ public:
false, false),
Val(val) {}
- /// \brief Build an empty imaginary literal.
+ /// Build an empty imaginary literal.
explicit ImaginaryLiteral(EmptyShell Empty)
: Expr(ImaginaryLiteralClass, Empty) { }
@@ -1551,7 +1609,7 @@ public:
return Create(C, Str, Kind, Pascal, Ty, &Loc, 1);
}
- /// \brief Construct an empty string literal.
+ /// Construct an empty string literal.
static StringLiteral *CreateEmpty(const ASTContext &C, unsigned NumStrs);
StringRef getString() const {
@@ -1590,7 +1648,7 @@ public:
unsigned getLength() const { return Length; }
unsigned getCharByteWidth() const { return CharByteWidth; }
- /// \brief Sets the string data to the given string data.
+ /// Sets the string data to the given string data.
void setString(const ASTContext &C, StringRef Str,
StringKind Kind, bool IsPascal);
@@ -1604,6 +1662,14 @@ public:
bool isUTF32() const { return Kind == UTF32; }
bool isPascal() const { return IsPascal; }
+ bool containsNonAscii() const {
+ StringRef Str = getString();
+ for (unsigned i = 0, e = Str.size(); i != e; ++i)
+ if (!isASCII(Str[i]))
+ return true;
+ return false;
+ }
+
bool containsNonAsciiOrNull() const {
StringRef Str = getString();
for (unsigned i = 0, e = Str.size(); i != e; ++i)
@@ -1674,7 +1740,7 @@ public:
val->containsUnexpandedParameterPack()),
L(l), R(r), Val(val) {}
- /// \brief Construct an empty parenthesized expression.
+ /// Construct an empty parenthesized expression.
explicit ParenExpr(EmptyShell Empty)
: Expr(ParenExprClass, Empty) { }
@@ -1685,11 +1751,11 @@ public:
SourceLocation getLocStart() const LLVM_READONLY { return L; }
SourceLocation getLocEnd() const LLVM_READONLY { return R; }
- /// \brief Get the location of the left parentheses '('.
+ /// Get the location of the left parentheses '('.
SourceLocation getLParen() const { return L; }
void setLParen(SourceLocation Loc) { L = Loc; }
- /// \brief Get the location of the right parentheses ')'.
+ /// Get the location of the right parentheses ')'.
SourceLocation getRParen() const { return R; }
void setRParen(SourceLocation Loc) { R = Loc; }
@@ -1720,21 +1786,21 @@ public:
private:
unsigned Opc : 5;
+ unsigned CanOverflow : 1;
SourceLocation Loc;
Stmt *Val;
public:
-
- UnaryOperator(Expr *input, Opcode opc, QualType type,
- ExprValueKind VK, ExprObjectKind OK, SourceLocation l)
- : Expr(UnaryOperatorClass, type, VK, OK,
- input->isTypeDependent() || type->isDependentType(),
- input->isValueDependent(),
- (input->isInstantiationDependent() ||
- type->isInstantiationDependentType()),
- input->containsUnexpandedParameterPack()),
- Opc(opc), Loc(l), Val(input) {}
-
- /// \brief Build an empty unary operator.
+ UnaryOperator(Expr *input, Opcode opc, QualType type, ExprValueKind VK,
+ ExprObjectKind OK, SourceLocation l, bool CanOverflow)
+ : Expr(UnaryOperatorClass, type, VK, OK,
+ input->isTypeDependent() || type->isDependentType(),
+ input->isValueDependent(),
+ (input->isInstantiationDependent() ||
+ type->isInstantiationDependentType()),
+ input->containsUnexpandedParameterPack()),
+ Opc(opc), CanOverflow(CanOverflow), Loc(l), Val(input) {}
+
+ /// Build an empty unary operator.
explicit UnaryOperator(EmptyShell Empty)
: Expr(UnaryOperatorClass, Empty), Opc(UO_AddrOf) { }
@@ -1748,6 +1814,15 @@ public:
SourceLocation getOperatorLoc() const { return Loc; }
void setOperatorLoc(SourceLocation L) { Loc = L; }
+ /// Returns true if the unary operator can cause an overflow. For instance,
+ /// signed int i = INT_MAX; i++;
+ /// signed char c = CHAR_MAX; c++;
+ /// Due to integer promotions, c++ is promoted to an int before the postfix
+ /// increment, and the result is an int that cannot overflow. However, i++
+ /// can overflow.
+ bool canOverflow() const { return CanOverflow; }
+ void setCanOverflow(bool C) { CanOverflow = C; }
+
/// isPostfix - Return true if this is a postfix operation, like x++.
static bool isPostfix(Opcode Op) {
return Op == UO_PostInc || Op == UO_PostDec;
@@ -1789,11 +1864,11 @@ public:
/// corresponds to, e.g. "sizeof" or "[pre]++"
static StringRef getOpcodeStr(Opcode Op);
- /// \brief Retrieve the unary opcode that corresponds to the given
+ /// Retrieve the unary opcode that corresponds to the given
/// overloaded operator.
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO, bool Postfix);
- /// \brief Retrieve the overloaded operator kind that corresponds to
+ /// Retrieve the overloaded operator kind that corresponds to
/// the given unary opcode.
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
@@ -1821,15 +1896,15 @@ public:
// __builtin_offsetof(type, identifier(.identifier|[expr])*)
class OffsetOfNode {
public:
- /// \brief The kind of offsetof node we have.
+ /// The kind of offsetof node we have.
enum Kind {
- /// \brief An index into an array.
+ /// An index into an array.
Array = 0x00,
- /// \brief A field.
+ /// A field.
Field = 0x01,
- /// \brief A field in a dependent type, known only by its name.
+ /// A field in a dependent type, known only by its name.
Identifier = 0x02,
- /// \brief An implicit indirection through a C++ base class, when the
+ /// An implicit indirection through a C++ base class, when the
/// field found is in a base class.
Base = 0x03
};
@@ -1837,10 +1912,10 @@ public:
private:
enum { MaskBits = 2, Mask = 0x03 };
- /// \brief The source range that covers this part of the designator.
+ /// The source range that covers this part of the designator.
SourceRange Range;
- /// \brief The data describing the designator, which comes in three
+ /// The data describing the designator, which comes in three
/// different forms, depending on the lower two bits.
/// - An unsigned index into the array of Expr*'s stored after this node
/// in memory, for [constant-expression] designators.
@@ -1852,53 +1927,53 @@ private:
uintptr_t Data;
public:
- /// \brief Create an offsetof node that refers to an array element.
+ /// Create an offsetof node that refers to an array element.
OffsetOfNode(SourceLocation LBracketLoc, unsigned Index,
SourceLocation RBracketLoc)
: Range(LBracketLoc, RBracketLoc), Data((Index << 2) | Array) {}
- /// \brief Create an offsetof node that refers to a field.
+ /// Create an offsetof node that refers to a field.
OffsetOfNode(SourceLocation DotLoc, FieldDecl *Field, SourceLocation NameLoc)
: Range(DotLoc.isValid() ? DotLoc : NameLoc, NameLoc),
Data(reinterpret_cast<uintptr_t>(Field) | OffsetOfNode::Field) {}
- /// \brief Create an offsetof node that refers to an identifier.
+ /// Create an offsetof node that refers to an identifier.
OffsetOfNode(SourceLocation DotLoc, IdentifierInfo *Name,
SourceLocation NameLoc)
: Range(DotLoc.isValid() ? DotLoc : NameLoc, NameLoc),
Data(reinterpret_cast<uintptr_t>(Name) | Identifier) {}
- /// \brief Create an offsetof node that refers into a C++ base class.
+ /// Create an offsetof node that refers into a C++ base class.
explicit OffsetOfNode(const CXXBaseSpecifier *Base)
: Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
- /// \brief Determine what kind of offsetof node this is.
+ /// Determine what kind of offsetof node this is.
Kind getKind() const { return static_cast<Kind>(Data & Mask); }
- /// \brief For an array element node, returns the index into the array
+ /// For an array element node, returns the index into the array
/// of expressions.
unsigned getArrayExprIndex() const {
assert(getKind() == Array);
return Data >> 2;
}
- /// \brief For a field offsetof node, returns the field.
+ /// For a field offsetof node, returns the field.
FieldDecl *getField() const {
assert(getKind() == Field);
return reinterpret_cast<FieldDecl *>(Data & ~(uintptr_t)Mask);
}
- /// \brief For a field or identifier offsetof node, returns the name of
+ /// For a field or identifier offsetof node, returns the name of
/// the field.
IdentifierInfo *getFieldName() const;
- /// \brief For a base class node, returns the base specifier.
+ /// For a base class node, returns the base specifier.
CXXBaseSpecifier *getBase() const {
assert(getKind() == Base);
return reinterpret_cast<CXXBaseSpecifier *>(Data & ~(uintptr_t)Mask);
}
- /// \brief Retrieve the source range that covers this offsetof node.
+ /// Retrieve the source range that covers this offsetof node.
///
/// For an array element node, the source range contains the locations of
/// the square brackets. For a field or identifier node, the source range
@@ -1961,7 +2036,7 @@ public:
SourceLocation getOperatorLoc() const { return OperatorLoc; }
void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
- /// \brief Return the location of the right parentheses.
+ /// Return the location of the right parentheses.
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation R) { RParenLoc = R; }
@@ -2055,7 +2130,7 @@ public:
QualType resultType, SourceLocation op,
SourceLocation rp);
- /// \brief Construct an empty sizeof/alignof expression.
+ /// Construct an empty sizeof/alignof expression.
explicit UnaryExprOrTypeTraitExpr(EmptyShell Empty)
: Expr(UnaryExprOrTypeTraitExprClass, Empty) { }
@@ -2138,7 +2213,7 @@ public:
SubExprs[RHS] = rhs;
}
- /// \brief Create an empty array subscript expression.
+ /// Create an empty array subscript expression.
explicit ArraySubscriptExpr(EmptyShell Shell)
: Expr(ArraySubscriptExprClass, Shell) { }
@@ -2160,19 +2235,19 @@ public:
void setRHS(Expr *E) { SubExprs[RHS] = E; }
Expr *getBase() {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getLHS():getRHS());
+ return getRHS()->getType()->isIntegerType() ? getLHS() : getRHS();
}
const Expr *getBase() const {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getLHS():getRHS());
+ return getRHS()->getType()->isIntegerType() ? getLHS() : getRHS();
}
Expr *getIdx() {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
+ return getRHS()->getType()->isIntegerType() ? getRHS() : getLHS();
}
const Expr *getIdx() const {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
+ return getRHS()->getType()->isIntegerType() ? getRHS() : getLHS();
}
SourceLocation getLocStart() const LLVM_READONLY {
@@ -2243,7 +2318,7 @@ public:
CallExpr(const ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t,
ExprValueKind VK, SourceLocation rparenloc);
- /// \brief Build an empty call expression.
+ /// Build an empty call expression.
CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty);
const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); }
@@ -2255,7 +2330,7 @@ public:
return const_cast<CallExpr*>(this)->getCalleeDecl();
}
- /// \brief If the callee is a FunctionDecl, return it. Otherwise return 0.
+ /// If the callee is a FunctionDecl, return it. Otherwise return 0.
FunctionDecl *getDirectCallee();
const FunctionDecl *getDirectCallee() const {
return const_cast<CallExpr*>(this)->getDirectCallee();
@@ -2265,7 +2340,7 @@ public:
///
unsigned getNumArgs() const { return NumArgs; }
- /// \brief Retrieve the call arguments.
+ /// Retrieve the call arguments.
Expr **getArgs() {
return reinterpret_cast<Expr **>(SubExprs+getNumPreArgs()+PREARGS_START);
}
@@ -2333,7 +2408,7 @@ public:
/// 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
+ /// Returns \c true if this is a call to a builtin which does not
/// evaluate side-effects within its arguments.
bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const;
@@ -2348,6 +2423,10 @@ public:
SourceLocation getLocStart() const LLVM_READONLY;
SourceLocation getLocEnd() const LLVM_READONLY;
+ /// Return true if this is a call to __assume() or __builtin_assume() with
+ /// a non-value-dependent constant parameter evaluating as false.
+ bool isBuiltinAssumeFalse(const ASTContext &Ctx) const;
+
bool isCallToStdMove() const {
const FunctionDecl* FD = getDirectCallee();
return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
@@ -2373,11 +2452,11 @@ public:
/// Extra data stored in some MemberExpr objects.
struct MemberExprNameQualifier {
- /// \brief The nested-name-specifier that qualifies the name, including
+ /// The nested-name-specifier that qualifies the name, including
/// source-location information.
NestedNameSpecifierLoc QualifierLoc;
- /// \brief The DeclAccessPair through which the MemberDecl was found due to
+ /// The DeclAccessPair through which the MemberDecl was found due to
/// name qualifiers.
DeclAccessPair FoundDecl;
};
@@ -2410,20 +2489,20 @@ class MemberExpr final
/// IsArrow - True if this is "X->F", false if this is "X.F".
bool IsArrow : 1;
- /// \brief True if this member expression used a nested-name-specifier to
+ /// True if this member expression used a nested-name-specifier to
/// refer to the member, e.g., "x->Base::f", or found its member via a using
/// declaration. When true, a MemberExprNameQualifier
/// structure is allocated immediately after the MemberExpr.
bool HasQualifierOrFoundDecl : 1;
- /// \brief True if this member expression specified a template keyword
+ /// True if this member expression specified a template keyword
/// and/or a template argument list explicitly, e.g., x->f<int>,
/// x->template f, x->template f<int>.
/// When true, an ASTTemplateKWAndArgsInfo structure and its
/// TemplateArguments (if any) are present.
bool HasTemplateKWAndArgsInfo : 1;
- /// \brief True if this member expression refers to a method that
+ /// True if this member expression refers to a method that
/// was resolved from an overloaded set having size greater than 1.
bool HadMultipleCandidates : 1;
@@ -2476,14 +2555,14 @@ public:
void setBase(Expr *E) { Base = E; }
Expr *getBase() const { return cast<Expr>(Base); }
- /// \brief Retrieve the member declaration to which this expression refers.
+ /// Retrieve the member declaration to which this expression refers.
///
/// The returned declaration will be a FieldDecl or (in C++) a VarDecl (for
/// static data members), a CXXMethodDecl, or an EnumConstantDecl.
ValueDecl *getMemberDecl() const { return MemberDecl; }
void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
- /// \brief Retrieves the declaration found by lookup.
+ /// Retrieves the declaration found by lookup.
DeclAccessPair getFoundDecl() const {
if (!HasQualifierOrFoundDecl)
return DeclAccessPair::make(getMemberDecl(),
@@ -2491,12 +2570,12 @@ public:
return getTrailingObjects<MemberExprNameQualifier>()->FoundDecl;
}
- /// \brief Determines whether this member expression actually had
+ /// 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() != nullptr; }
- /// \brief If the member name was qualified, retrieves the
+ /// If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name, with source-location
/// information.
NestedNameSpecifierLoc getQualifierLoc() const {
@@ -2506,28 +2585,28 @@ public:
return getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc;
}
- /// \brief If the member name was qualified, retrieves the
+ /// If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name. Otherwise, returns
/// NULL.
NestedNameSpecifier *getQualifier() const {
return getQualifierLoc().getNestedNameSpecifier();
}
- /// \brief Retrieve the location of the template keyword preceding
+ /// Retrieve the location of the template keyword preceding
/// the member name, if any.
SourceLocation getTemplateKeywordLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
}
- /// \brief Retrieve the location of the left angle bracket starting the
+ /// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the member name, if any.
SourceLocation getLAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
}
- /// \brief Retrieve the location of the right angle bracket ending the
+ /// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the member name, if any.
SourceLocation getRAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
@@ -2537,11 +2616,11 @@ public:
/// Determines whether the member name was preceded by the template keyword.
bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
- /// \brief Determines whether the member name was followed by an
+ /// Determines whether the member name was followed by an
/// explicit template argument list.
bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
- /// \brief Copies the template arguments (if present) into the given
+ /// Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgs())
@@ -2549,7 +2628,7 @@ public:
getTrailingObjects<TemplateArgumentLoc>(), List);
}
- /// \brief Retrieve the template arguments provided as part of this
+ /// Retrieve the template arguments provided as part of this
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
@@ -2558,7 +2637,7 @@ public:
return getTrailingObjects<TemplateArgumentLoc>();
}
- /// \brief Retrieve the number of template arguments provided as part of this
+ /// Retrieve the number of template arguments provided as part of this
/// template-id.
unsigned getNumTemplateArgs() const {
if (!hasExplicitTemplateArgs())
@@ -2571,7 +2650,7 @@ public:
return {getTemplateArgs(), getNumTemplateArgs()};
}
- /// \brief Retrieve the member declaration name info.
+ /// Retrieve the member declaration name info.
DeclarationNameInfo getMemberNameInfo() const {
return DeclarationNameInfo(MemberDecl->getDeclName(),
MemberLoc, MemberDNLoc);
@@ -2592,24 +2671,24 @@ public:
SourceLocation getExprLoc() const LLVM_READONLY { return MemberLoc; }
- /// \brief Determine whether the base of this explicit is implicit.
+ /// Determine whether the base of this explicit is implicit.
bool isImplicitAccess() const {
return getBase() && getBase()->isImplicitCXXThis();
}
- /// \brief Returns true if this member expression refers to a method that
+ /// Returns true if this member expression refers to a method that
/// was resolved from an overloaded set having size greater than 1.
bool hadMultipleCandidates() const {
return HadMultipleCandidates;
}
- /// \brief Sets the flag telling whether this expression refers to
+ /// Sets the flag telling whether this expression refers to
/// a method that was resolved from an overloaded set having size
/// greater than 1.
void setHadMultipleCandidates(bool V = true) {
HadMultipleCandidates = V;
}
- /// \brief Returns true if virtual dispatch is performed.
+ /// Returns true if virtual dispatch is performed.
/// If the member access is fully qualified, (i.e. X::f()), virtual
/// dispatching is not performed. In -fapple-kext mode qualified
/// calls to virtual method will still go through the vtable.
@@ -2656,7 +2735,7 @@ public:
init->containsUnexpandedParameterPack()),
LParenLoc(lparenloc), TInfoAndScope(tinfo, fileScope), Init(init) {}
- /// \brief Construct an empty compound literal.
+ /// Construct an empty compound literal.
explicit CompoundLiteralExpr(EmptyShell Empty)
: Expr(CompoundLiteralExprClass, Empty) { }
@@ -2743,26 +2822,30 @@ protected:
(op && op->containsUnexpandedParameterPack()))),
Op(op) {
CastExprBits.Kind = kind;
+ CastExprBits.PartOfExplicitCast = false;
setBasePathSize(BasePathSize);
assert(CastConsistency());
}
- /// \brief Construct an empty cast.
+ /// Construct an empty cast.
CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
: Expr(SC, Empty) {
+ CastExprBits.PartOfExplicitCast = false;
setBasePathSize(BasePathSize);
}
public:
CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; }
void setCastKind(CastKind K) { CastExprBits.Kind = K; }
- const char *getCastKindName() const;
+
+ static const char *getCastKindName(CastKind CK);
+ const char *getCastKindName() const { return getCastKindName(getCastKind()); }
Expr *getSubExpr() { return cast<Expr>(Op); }
const Expr *getSubExpr() const { return cast<Expr>(Op); }
void setSubExpr(Expr *E) { Op = E; }
- /// \brief Retrieve the cast subexpression as it was written in the source
+ /// Retrieve the cast subexpression as it was written in the source
/// code, looking through any implicit casts or other intermediate nodes
/// introduced by semantic analysis.
Expr *getSubExprAsWritten();
@@ -2770,6 +2853,10 @@ public:
return const_cast<CastExpr *>(this)->getSubExprAsWritten();
}
+ /// If this cast applies a user-defined conversion, retrieve the conversion
+ /// function that it invokes.
+ NamedDecl *getConversionFunction() const;
+
typedef CXXBaseSpecifier **path_iterator;
typedef const CXXBaseSpecifier * const *path_const_iterator;
bool path_empty() const { return CastExprBits.BasePathSize == 0; }
@@ -2828,7 +2915,7 @@ private:
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) {
}
- /// \brief Construct an empty implicit cast.
+ /// Construct an empty implicit cast.
explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize)
: CastExpr(ImplicitCastExprClass, Shell, PathSize) { }
@@ -2839,6 +2926,11 @@ public:
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) {
}
+ bool isPartOfExplicitCast() const { return CastExprBits.PartOfExplicitCast; }
+ void setIsPartOfExplicitCast(bool PartOfExplicitCast) {
+ CastExprBits.PartOfExplicitCast = PartOfExplicitCast;
+ }
+
static ImplicitCastExpr *Create(const ASTContext &Context, QualType T,
CastKind Kind, Expr *Operand,
const CXXCastPath *BasePath,
@@ -2896,7 +2988,7 @@ protected:
TypeSourceInfo *writtenTy)
: CastExpr(SC, exprTy, VK, kind, op, PathSize), TInfo(writtenTy) {}
- /// \brief Construct an empty explicit cast.
+ /// Construct an empty explicit cast.
ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
: CastExpr(SC, Shell, PathSize) { }
@@ -2931,7 +3023,7 @@ class CStyleCastExpr final
: ExplicitCastExpr(CStyleCastExprClass, exprTy, vk, kind, op, PathSize,
writtenTy), LPLoc(l), RPLoc(r) {}
- /// \brief Construct an empty C-style explicit cast.
+ /// Construct an empty C-style explicit cast.
explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
: ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
@@ -2964,7 +3056,7 @@ public:
friend class CastExpr;
};
-/// \brief A builtin binary operation expression such as "x + y" or "x <= y".
+/// A builtin binary operation expression such as "x + y" or "x <= y".
///
/// This expression node kind describes a builtin binary operation,
/// such as "x + y" for integer values "x" and "y". The operands will
@@ -3015,7 +3107,7 @@ public:
"Use CompoundAssignOperator for compound assignments");
}
- /// \brief Construct an empty binary operator.
+ /// Construct an empty binary operator.
explicit BinaryOperator(EmptyShell Empty)
: Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { }
@@ -3044,11 +3136,11 @@ public:
StringRef getOpcodeStr() const { return getOpcodeStr(getOpcode()); }
- /// \brief Retrieve the binary opcode that corresponds to the given
+ /// Retrieve the binary opcode that corresponds to the given
/// overloaded operator.
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO);
- /// \brief Retrieve the overloaded operator kind that corresponds to
+ /// Retrieve the overloaded operator kind that corresponds to
/// the given binary opcode.
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
@@ -3078,7 +3170,7 @@ public:
static Opcode negateComparisonOp(Opcode Opc) {
switch (Opc) {
default:
- llvm_unreachable("Not a comparsion operator.");
+ llvm_unreachable("Not a comparison operator.");
case BO_LT: return BO_GE;
case BO_GT: return BO_LE;
case BO_LE: return BO_GT;
@@ -3091,7 +3183,7 @@ public:
static Opcode reverseComparisonOp(Opcode Opc) {
switch (Opc) {
default:
- llvm_unreachable("Not a comparsion operator.");
+ llvm_unreachable("Not a comparison operator.");
case BO_LT: return BO_GT;
case BO_GT: return BO_LT;
case BO_LE: return BO_GE;
@@ -3204,7 +3296,7 @@ public:
"Only should be used for compound assignments");
}
- /// \brief Build an empty compound assignment operator expression.
+ /// Build an empty compound assignment operator expression.
explicit CompoundAssignOperator(EmptyShell Empty)
: BinaryOperator(CompoundAssignOperatorClass, Empty) { }
@@ -3294,7 +3386,7 @@ public:
SubExprs[RHS] = rhs;
}
- /// \brief Build an empty conditional operator.
+ /// Build an empty conditional operator.
explicit ConditionalOperator(EmptyShell Empty)
: AbstractConditionalOperator(ConditionalOperatorClass, Empty) { }
@@ -3372,30 +3464,30 @@ public:
assert(OpaqueValue->getSourceExpr() == common && "Wrong opaque value");
}
- /// \brief Build an empty conditional operator.
+ /// Build an empty conditional operator.
explicit BinaryConditionalOperator(EmptyShell Empty)
: AbstractConditionalOperator(BinaryConditionalOperatorClass, Empty) { }
- /// \brief getCommon - Return the common expression, written to the
+ /// getCommon - Return the common expression, written to the
/// left of the condition. The opaque value will be bound to the
/// result of this expression.
Expr *getCommon() const { return cast<Expr>(SubExprs[COMMON]); }
- /// \brief getOpaqueValue - Return the opaque value placeholder.
+ /// getOpaqueValue - Return the opaque value placeholder.
OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
- /// \brief getCond - Return the condition expression; this is defined
+ /// getCond - Return the condition expression; this is defined
/// in terms of the opaque value.
Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
- /// \brief getTrueExpr - Return the subexpression which will be
+ /// getTrueExpr - Return the subexpression which will be
/// evaluated if the condition evaluates to true; this is defined
/// in terms of the opaque value.
Expr *getTrueExpr() const {
return cast<Expr>(SubExprs[LHS]);
}
- /// \brief getFalseExpr - Return the subexpression which will be
+ /// getFalseExpr - Return the subexpression which will be
/// evaluated if the condnition evaluates to false; this is
/// defined in terms of the opaque value.
Expr *getFalseExpr() const {
@@ -3451,7 +3543,7 @@ public:
false),
AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {}
- /// \brief Build an empty address of a label expression.
+ /// Build an empty address of a label expression.
explicit AddrLabelExpr(EmptyShell Empty)
: Expr(AddrLabelExprClass, Empty) { }
@@ -3498,7 +3590,7 @@ public:
T->isDependentType(), false, false, false),
SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { }
- /// \brief Build an empty statement expression.
+ /// Build an empty statement expression.
explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) { }
CompoundStmt *getSubStmt() { return cast<CompoundStmt>(SubStmt); }
@@ -3544,7 +3636,7 @@ public:
ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args, QualType Type,
SourceLocation BLoc, SourceLocation RP);
- /// \brief Build an empty vector-shuffle expression.
+ /// Build an empty vector-shuffle expression.
explicit ShuffleVectorExpr(EmptyShell Empty)
: Expr(ShuffleVectorExprClass, Empty), SubExprs(nullptr) { }
@@ -3566,7 +3658,7 @@ public:
/// pointers.
unsigned getNumSubExprs() const { return NumExprs; }
- /// \brief Retrieve the array of expressions.
+ /// Retrieve the array of expressions.
Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
/// getExpr - Return the Expr at the specified index.
@@ -3684,7 +3776,7 @@ public:
SubExprs[RHS] = rhs;
}
- /// \brief Build an empty __builtin_choose_expr.
+ /// Build an empty __builtin_choose_expr.
explicit ChooseExpr(EmptyShell Empty) : Expr(ChooseExprClass, Empty) { }
/// isConditionTrue - Return whether the condition is true (i.e. not
@@ -3751,7 +3843,7 @@ public:
false),
TokenLoc(Loc) { }
- /// \brief Build an empty GNU __null expression.
+ /// Build an empty GNU __null expression.
explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) { }
/// getTokenLocation - The location of the __null token.
@@ -3824,7 +3916,7 @@ public:
}
};
-/// @brief Describes an C or C++ initializer list.
+/// Describes an C or C++ initializer list.
///
/// InitListExpr describes an initializer list, which can be used to
/// initialize objects of different types, including
@@ -3882,7 +3974,7 @@ class InitListExpr : public Expr {
/// - the semantic form, if this is in syntactic form.
llvm::PointerIntPair<InitListExpr *, 1, bool> AltForm;
- /// \brief Either:
+ /// Either:
/// If this initializer list initializes an array with more elements than
/// there are initializers in the list, specifies an expression to be used
/// for value initialization of the rest of the elements.
@@ -3895,16 +3987,16 @@ public:
InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
ArrayRef<Expr*> initExprs, SourceLocation rbraceloc);
- /// \brief Build an empty initializer list.
+ /// Build an empty initializer list.
explicit InitListExpr(EmptyShell Empty)
: Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
unsigned getNumInits() const { return InitExprs.size(); }
- /// \brief Retrieve the set of initializers.
+ /// Retrieve the set of initializers.
Expr **getInits() { return reinterpret_cast<Expr **>(InitExprs.data()); }
- /// \brief Retrieve the set of initializers.
+ /// Retrieve the set of initializers.
Expr * const *getInits() const {
return reinterpret_cast<Expr * const *>(InitExprs.data());
}
@@ -3940,10 +4032,10 @@ public:
}
}
- /// \brief Reserve space for some number of initializers.
+ /// Reserve space for some number of initializers.
void reserveInits(const ASTContext &C, unsigned NumInits);
- /// @brief Specify the number of initializers
+ /// Specify the number of initializers
///
/// If there are more than @p NumInits initializers, the remaining
/// initializers will be destroyed. If there are fewer than @p
@@ -3951,7 +4043,7 @@ public:
/// unknown initializers.
void resizeInits(const ASTContext &Context, unsigned NumInits);
- /// @brief Updates the initializer at index @p Init with the new
+ /// Updates the initializer at index @p Init with the new
/// expression @p expr, and returns the old expression at that
/// location.
///
@@ -3960,7 +4052,7 @@ public:
/// accommodate the new entry.
Expr *updateInit(const ASTContext &C, unsigned Init, Expr *expr);
- /// \brief If this initializer list initializes an array with more elements
+ /// If this initializer list initializes an array with more elements
/// than there are initializers in the list, specifies an expression to be
/// used for value initialization of the rest of the elements.
Expr *getArrayFiller() {
@@ -3971,11 +4063,11 @@ public:
}
void setArrayFiller(Expr *filler);
- /// \brief Return true if this is an array initializer and its array "filler"
+ /// Return true if this is an array initializer and its array "filler"
/// has been set.
bool hasArrayFiller() const { return getArrayFiller(); }
- /// \brief If this initializes a union, specifies which field in the
+ /// If this initializes a union, specifies which field in the
/// union to initialize.
///
/// Typically, this field is the first named field within the
@@ -4083,7 +4175,7 @@ public:
friend class ASTStmtWriter;
};
-/// @brief Represents a C99 designated initializer expression.
+/// Represents a C99 designated initializer expression.
///
/// A designated initializer expression (C99 6.7.8) contains one or
/// more designators (which can be field designators, array
@@ -4107,7 +4199,7 @@ class DesignatedInitExpr final
: public Expr,
private llvm::TrailingObjects<DesignatedInitExpr, Stmt *> {
public:
- /// \brief Forward declaration of the Designator class.
+ /// Forward declaration of the Designator class.
class Designator;
private:
@@ -4127,7 +4219,7 @@ private:
/// expressions used by array and array-range designators.
unsigned NumSubExprs : 16;
- /// \brief The designators in this designated initialization
+ /// The designators in this designated initialization
/// expression.
Designator *Designators;
@@ -4172,14 +4264,14 @@ public:
unsigned RBracketLoc;
};
- /// @brief Represents a single C99 designator.
+ /// Represents a single C99 designator.
///
/// @todo This class is infuriatingly similar to clang::Designator,
/// but minor differences (storing indices vs. storing pointers)
/// keep us from reusing it. Try harder, later, to rectify these
/// differences.
class Designator {
- /// @brief The kind of designator this describes.
+ /// The kind of designator this describes.
enum {
FieldDesignator,
ArrayDesignator,
@@ -4197,7 +4289,7 @@ public:
public:
Designator() {}
- /// @brief Initializes a field designator.
+ /// Initializes a field designator.
Designator(const IdentifierInfo *FieldName, SourceLocation DotLoc,
SourceLocation FieldLoc)
: Kind(FieldDesignator) {
@@ -4206,7 +4298,7 @@ public:
Field.FieldLoc = FieldLoc.getRawEncoding();
}
- /// @brief Initializes an array designator.
+ /// Initializes an array designator.
Designator(unsigned Index, SourceLocation LBracketLoc,
SourceLocation RBracketLoc)
: Kind(ArrayDesignator) {
@@ -4216,7 +4308,7 @@ public:
ArrayOrRange.RBracketLoc = RBracketLoc.getRawEncoding();
}
- /// @brief Initializes a GNU array-range designator.
+ /// Initializes a GNU array-range designator.
Designator(unsigned Index, SourceLocation LBracketLoc,
SourceLocation EllipsisLoc, SourceLocation RBracketLoc)
: Kind(ArrayRangeDesignator) {
@@ -4302,7 +4394,7 @@ public:
static DesignatedInitExpr *CreateEmpty(const ASTContext &C,
unsigned NumIndexExprs);
- /// @brief Returns the number of designators in this initializer.
+ /// Returns the number of designators in this initializer.
unsigned size() const { return NumDesignators; }
// Iterator access to the designators.
@@ -4326,17 +4418,17 @@ public:
Expr *getArrayRangeStart(const Designator &D) const;
Expr *getArrayRangeEnd(const Designator &D) const;
- /// @brief Retrieve the location of the '=' that precedes the
+ /// Retrieve the location of the '=' that precedes the
/// initializer value itself, if present.
SourceLocation getEqualOrColonLoc() const { return EqualOrColonLoc; }
void setEqualOrColonLoc(SourceLocation L) { EqualOrColonLoc = L; }
- /// @brief Determines whether this designated initializer used the
+ /// Determines whether this designated initializer used the
/// deprecated GNU syntax for designated initializers.
bool usesGNUSyntax() const { return GNUSyntax; }
void setGNUSyntax(bool GNU) { GNUSyntax = GNU; }
- /// @brief Retrieve the initializer value.
+ /// Retrieve the initializer value.
Expr *getInit() const {
return cast<Expr>(*const_cast<DesignatedInitExpr*>(this)->child_begin());
}
@@ -4345,7 +4437,7 @@ public:
*child_begin() = init;
}
- /// \brief Retrieve the total number of subexpressions in this
+ /// Retrieve the total number of subexpressions in this
/// designated initializer expression, including the actual
/// initialized value and any expressions that occur within array
/// and array-range designators.
@@ -4361,7 +4453,7 @@ public:
getTrailingObjects<Stmt *>()[Idx] = E;
}
- /// \brief Replaces the designator at index @p Idx with the series
+ /// Replaces the designator at index @p Idx with the series
/// of designators in [First, Last).
void ExpandDesignator(const ASTContext &C, unsigned Idx,
const Designator *First, const Designator *Last);
@@ -4388,7 +4480,7 @@ public:
friend TrailingObjects;
};
-/// \brief Represents a place-holder for an object not to be initialized by
+/// Represents a place-holder for an object not to be initialized by
/// anything.
///
/// This only makes sense when it appears as part of an updater of a
@@ -4471,7 +4563,7 @@ public:
}
};
-/// \brief Represents a loop initializing the elements of an array.
+/// Represents a loop initializing the elements of an array.
///
/// The need to initialize the elements of an array occurs in a number of
/// contexts:
@@ -4539,7 +4631,7 @@ public:
friend class ASTStmtWriter;
};
-/// \brief Represents the index of the current element of an array being
+/// Represents the index of the current element of an array being
/// initialized by an ArrayInitLoopExpr. This can only appear within the
/// subexpression of an ArrayInitLoopExpr.
class ArrayInitIndexExpr : public Expr {
@@ -4569,7 +4661,7 @@ public:
friend class ASTStmtReader;
};
-/// \brief Represents an implicitly-generated value initialization of
+/// Represents an implicitly-generated value initialization of
/// an object of a given type.
///
/// Implicit value initializations occur within semantic initializer
@@ -4583,7 +4675,7 @@ public:
: Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary,
false, false, ty->isInstantiationDependentType(), false) { }
- /// \brief Construct an empty implicit value initialization.
+ /// Construct an empty implicit value initialization.
explicit ImplicitValueInitExpr(EmptyShell Empty)
: Expr(ImplicitValueInitExprClass, Empty) { }
@@ -4612,7 +4704,7 @@ public:
ParenListExpr(const ASTContext& C, SourceLocation lparenloc,
ArrayRef<Expr*> exprs, SourceLocation rparenloc);
- /// \brief Build an empty paren list.
+ /// Build an empty paren list.
explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
unsigned getNumExprs() const { return NumExprs; }
@@ -4655,7 +4747,7 @@ public:
friend class ASTStmtWriter;
};
-/// \brief Represents a C11 generic selection.
+/// Represents a C11 generic selection.
///
/// A generic selection (C11 6.5.1.1) contains an unevaluated controlling
/// expression, followed by one or more generic associations. Each generic
@@ -4801,7 +4893,7 @@ public:
base->containsUnexpandedParameterPack()),
Base(base), Accessor(&accessor), AccessorLoc(loc) {}
- /// \brief Build an empty vector element expression.
+ /// Build an empty vector element expression.
explicit ExtVectorElementExpr(EmptyShell Empty)
: Expr(ExtVectorElementExprClass, Empty) { }
@@ -4859,7 +4951,7 @@ public:
false),
TheBlock(BD) {}
- /// \brief Build an empty block expression.
+ /// Build an empty block expression.
explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) { }
const BlockDecl *getBlockDecl() const { return TheBlock; }
@@ -5111,7 +5203,7 @@ public:
};
private:
- /// \brief Location of sub-expressions.
+ /// Location of sub-expressions.
/// The location of Scope sub-expression is NumSubExprs - 1, which is
/// not fixed, therefore is not defined in enum.
enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
@@ -5125,11 +5217,11 @@ public:
AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t,
AtomicOp op, SourceLocation RP);
- /// \brief Determine the number of arguments the specified atomic builtin
+ /// Determine the number of arguments the specified atomic builtin
/// should have.
static unsigned getNumSubExprs(AtomicOp Op);
- /// \brief Build an empty AtomicExpr.
+ /// Build an empty AtomicExpr.
explicit AtomicExpr(EmptyShell Empty) : Expr(AtomicExprClass, Empty) { }
Expr *getPtr() const {
@@ -5208,7 +5300,7 @@ public:
return const_child_range(SubExprs, SubExprs + NumSubExprs);
}
- /// \brief Get atomic scope model for the atomic op code.
+ /// Get atomic scope model for the atomic op code.
/// \return empty atomic scope model if the atomic op code does not have
/// scope operand.
static std::unique_ptr<AtomicScopeModel> getScopeModel(AtomicOp Op) {
@@ -5219,7 +5311,7 @@ public:
return AtomicScopeModel::create(Kind);
}
- /// \brief Get atomic scope model.
+ /// Get atomic scope model.
/// \return empty atomic scope model if this atomic expression does not have
/// scope operand.
std::unique_ptr<AtomicScopeModel> getScopeModel() const {
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 58054dda31aa8..8206a26b2c4b5 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Defines the clang::Expr interface and subclasses for C++ expressions.
+/// Defines the clang::Expr interface and subclasses for C++ expressions.
//
//===----------------------------------------------------------------------===//
@@ -62,7 +62,7 @@ class TemplateParameterList;
// C++ Expressions.
//===--------------------------------------------------------------------===//
-/// \brief A call to an overloaded operator written using operator
+/// A call to an overloaded operator written using operator
/// syntax.
///
/// Represents a call to an overloaded operator written using operator
@@ -76,7 +76,7 @@ class TemplateParameterList;
/// function templates that were found by name lookup at template
/// definition time.
class CXXOperatorCallExpr : public CallExpr {
- /// \brief The overloaded operator.
+ /// The overloaded operator.
OverloadedOperatorKind Operator;
SourceRange Range;
@@ -101,7 +101,7 @@ public:
explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty)
: CallExpr(C, CXXOperatorCallExprClass, Empty) {}
- /// \brief Returns the kind of overloaded operator that this
+ /// Returns the kind of overloaded operator that this
/// expression refers to.
OverloadedOperatorKind getOperator() const { return Operator; }
@@ -115,10 +115,10 @@ public:
}
bool isAssignmentOp() const { return isAssignmentOp(getOperator()); }
- /// \brief Is this written as an infix binary operator?
+ /// Is this written as an infix binary operator?
bool isInfixBinaryOp() const;
- /// \brief Returns the location of the operator symbol in the expression.
+ /// Returns the location of the operator symbol in the expression.
///
/// When \c getOperator()==OO_Call, this is the location of the right
/// parentheses; when \c getOperator()==OO_Subscript, this is the location
@@ -170,15 +170,15 @@ public:
CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
: CallExpr(C, CXXMemberCallExprClass, Empty) {}
- /// \brief Retrieves the implicit object argument for the member call.
+ /// Retrieves the implicit object argument for the member call.
///
/// For example, in "x.f(5)", this returns the sub-expression "x".
Expr *getImplicitObjectArgument() const;
- /// \brief Retrieves the declaration of the called method.
+ /// Retrieves the declaration of the called method.
CXXMethodDecl *getMethodDecl() const;
- /// \brief Retrieves the CXXRecordDecl for the underlying type of
+ /// Retrieves the CXXRecordDecl for the underlying type of
/// the implicit object argument.
///
/// Note that this is may not be the same declaration as that of the class
@@ -199,7 +199,7 @@ public:
}
};
-/// \brief Represents a call to a CUDA kernel function.
+/// Represents a call to a CUDA kernel function.
class CUDAKernelCallExpr : public CallExpr {
private:
enum { CONFIG, END_PREARG };
@@ -218,7 +218,7 @@ public:
}
CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); }
- /// \brief Sets the kernel configuration expression.
+ /// Sets the kernel configuration expression.
///
/// Note that this method cannot be called if config has already been set to a
/// non-null value.
@@ -237,7 +237,7 @@ public:
}
};
-/// \brief Abstract class common to all of the C++ "named"/"keyword" casts.
+/// Abstract class common to all of the C++ "named"/"keyword" casts.
///
/// This abstract class is inherited by all of the classes
/// representing "named" casts: CXXStaticCastExpr for \c static_cast,
@@ -271,11 +271,11 @@ protected:
public:
const char *getCastName() const;
- /// \brief Retrieve the location of the cast operator keyword, e.g.,
+ /// Retrieve the location of the cast operator keyword, e.g.,
/// \c static_cast.
SourceLocation getOperatorLoc() const { return Loc; }
- /// \brief Retrieve the location of the closing parenthesis.
+ /// Retrieve the location of the closing parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; }
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
@@ -295,7 +295,7 @@ public:
}
};
-/// \brief A C++ \c static_cast expression (C++ [expr.static.cast]).
+/// A C++ \c static_cast expression (C++ [expr.static.cast]).
///
/// This expression node represents a C++ static cast, e.g.,
/// \c static_cast<int>(1.0).
@@ -330,7 +330,7 @@ public:
}
};
-/// \brief A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]).
+/// A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]).
///
/// This expression node represents a dynamic cast, e.g.,
/// \c dynamic_cast<Derived*>(BasePtr). Such a cast may perform a run-time
@@ -369,7 +369,7 @@ public:
}
};
-/// \brief A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]).
+/// A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]).
///
/// This expression node represents a reinterpret cast, e.g.,
/// @c reinterpret_cast<int>(VoidPtr).
@@ -410,7 +410,7 @@ public:
}
};
-/// \brief A C++ \c const_cast expression (C++ [expr.const.cast]).
+/// A C++ \c const_cast expression (C++ [expr.const.cast]).
///
/// This expression node represents a const cast, e.g.,
/// \c const_cast<char*>(PtrToConstChar).
@@ -445,7 +445,7 @@ public:
}
};
-/// \brief A call to a literal operator (C++11 [over.literal])
+/// A call to a literal operator (C++11 [over.literal])
/// written as a user-defined literal (C++11 [lit.ext]).
///
/// Represents a user-defined literal, e.g. "foo"_bar or 1.23_xyz. While this
@@ -455,7 +455,7 @@ public:
/// Since literal operators are never found by ADL and can only be declared at
/// namespace scope, a user-defined literal is never dependent.
class UserDefinedLiteral : public CallExpr {
- /// \brief The location of a ud-suffix within the literal.
+ /// The location of a ud-suffix within the literal.
SourceLocation UDSuffixLoc;
public:
@@ -492,11 +492,11 @@ public:
LOK_Character
};
- /// \brief Returns the kind of literal operator invocation
+ /// Returns the kind of literal operator invocation
/// which this expression represents.
LiteralOperatorKind getLiteralOperatorKind() const;
- /// \brief If this is not a raw user-defined literal, get the
+ /// If this is not a raw user-defined literal, get the
/// underlying cooked literal (representing the literal with the suffix
/// removed).
Expr *getCookedLiteral();
@@ -512,13 +512,13 @@ public:
SourceLocation getLocEnd() const { return getRParenLoc(); }
- /// \brief Returns the location of a ud-suffix in the expression.
+ /// Returns the location of a ud-suffix in the expression.
///
/// For a string literal, there may be multiple identical suffixes. This
/// returns the first.
SourceLocation getUDSuffixLoc() const { return UDSuffixLoc; }
- /// \brief Returns the ud-suffix specified for this literal.
+ /// Returns the ud-suffix specified for this literal.
const IdentifierInfo *getUDSuffix() const;
static bool classof(const Stmt *S) {
@@ -526,7 +526,7 @@ public:
}
};
-/// \brief A boolean literal, per ([C++ lex.bool] Boolean literals).
+/// A boolean literal, per ([C++ lex.bool] Boolean literals).
class CXXBoolLiteralExpr : public Expr {
bool Value;
SourceLocation Loc;
@@ -559,7 +559,7 @@ public:
}
};
-/// \brief The null pointer literal (C++11 [lex.nullptr])
+/// The null pointer literal (C++11 [lex.nullptr])
///
/// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr.
class CXXNullPtrLiteralExpr : public Expr {
@@ -589,7 +589,7 @@ public:
}
};
-/// \brief Implicit construction of a std::initializer_list<T> object from an
+/// Implicit construction of a std::initializer_list<T> object from an
/// array temporary within list-initialization (C++11 [dcl.init.list]p5).
class CXXStdInitializerListExpr : public Expr {
Stmt *SubExpr = nullptr;
@@ -619,6 +619,7 @@ public:
return SubExpr->getLocEnd();
}
+ /// Retrieve the source range of the expression.
SourceRange getSourceRange() const LLVM_READONLY {
return SubExpr->getSourceRange();
}
@@ -677,11 +678,11 @@ public:
bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
- /// \brief Retrieves the type operand of this typeid() expression after
+ /// Retrieves the type operand of this typeid() expression after
/// various required adjustments (removing reference types, cv-qualifiers).
QualType getTypeOperand(ASTContext &Context) const;
- /// \brief Retrieve source information for the type operand.
+ /// Retrieve source information for the type operand.
TypeSourceInfo *getTypeOperandSourceInfo() const {
assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
return Operand.get<TypeSourceInfo *>();
@@ -715,12 +716,12 @@ public:
child_range children() {
if (isTypeOperand())
return child_range(child_iterator(), child_iterator());
- Stmt **begin = reinterpret_cast<Stmt**>(&Operand);
+ auto **begin = reinterpret_cast<Stmt **>(&Operand);
return child_range(begin, begin + 1);
}
};
-/// \brief A member reference to an MSPropertyDecl.
+/// A member reference to an MSPropertyDecl.
///
/// This expression always has pseudo-object type, and therefore it is
/// typically not encountered in a fully-typechecked expression except
@@ -816,7 +817,7 @@ public:
SubExprs[IDX_EXPR] = Idx;
}
- /// \brief Create an empty array subscript expression.
+ /// Create an empty array subscript expression.
explicit MSPropertySubscriptExpr(EmptyShell Shell)
: Expr(MSPropertySubscriptExprClass, Shell) {}
@@ -884,11 +885,11 @@ public:
bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
- /// \brief Retrieves the type operand of this __uuidof() expression after
+ /// Retrieves the type operand of this __uuidof() expression after
/// various required adjustments (removing reference types, cv-qualifiers).
QualType getTypeOperand(ASTContext &Context) const;
- /// \brief Retrieve source information for the type operand.
+ /// Retrieve source information for the type operand.
TypeSourceInfo *getTypeOperandSourceInfo() const {
assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
return Operand.get<TypeSourceInfo *>();
@@ -925,12 +926,12 @@ public:
child_range children() {
if (isTypeOperand())
return child_range(child_iterator(), child_iterator());
- Stmt **begin = reinterpret_cast<Stmt**>(&Operand);
+ auto **begin = reinterpret_cast<Stmt **>(&Operand);
return child_range(begin, begin + 1);
}
};
-/// \brief Represents the \c this expression in C++.
+/// Represents the \c this expression in C++.
///
/// This is a pointer to the object on which the current member function is
/// executing (C++ [expr.prim]p3). Example:
@@ -977,7 +978,7 @@ public:
}
};
-/// \brief A C++ throw-expression (C++ [except.throw]).
+/// A C++ throw-expression (C++ [except.throw]).
///
/// This handles 'throw' (for re-throwing the current exception) and
/// 'throw' assignment-expression. When assignment-expression isn't
@@ -988,7 +989,7 @@ class CXXThrowExpr : public Expr {
Stmt *Op;
SourceLocation ThrowLoc;
- /// \brief Whether the thrown variable (if any) is in scope.
+ /// Whether the thrown variable (if any) is in scope.
unsigned IsThrownVariableInScope : 1;
public:
@@ -1009,7 +1010,7 @@ public:
SourceLocation getThrowLoc() const { return ThrowLoc; }
- /// \brief Determines whether the variable thrown by this expression (if any!)
+ /// Determines whether the variable thrown by this expression (if any!)
/// is within the innermost try block.
///
/// This information is required to determine whether the NRVO can apply to
@@ -1034,16 +1035,16 @@ public:
}
};
-/// \brief A default argument (C++ [dcl.fct.default]).
+/// A default argument (C++ [dcl.fct.default]).
///
/// This wraps up a function call argument that was created from the
/// corresponding parameter's default argument, when the call did not
/// explicitly supply arguments for all of the parameters.
class CXXDefaultArgExpr final : public Expr {
- /// \brief The parameter whose default is being used.
+ /// The parameter whose default is being used.
ParmVarDecl *Param;
- /// \brief The location where the default argument expression was used.
+ /// The location where the default argument expression was used.
SourceLocation Loc;
CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param)
@@ -1081,7 +1082,7 @@ public:
return getParam()->getDefaultArg();
}
- /// \brief Retrieve the location where this default argument was actually
+ /// Retrieve the location where this default argument was actually
/// used.
SourceLocation getUsedLocation() const { return Loc; }
@@ -1102,7 +1103,7 @@ public:
}
};
-/// \brief A use of a default initializer in a constructor or in aggregate
+/// A use of a default initializer in a constructor or in aggregate
/// initialization.
///
/// This wraps a use of a C++ default initializer (technically,
@@ -1111,10 +1112,10 @@ public:
/// (C++11 [class.base.init]p8) or in aggregate initialization
/// (C++1y [dcl.init.aggr]p7).
class CXXDefaultInitExpr : public Expr {
- /// \brief The field whose default is being used.
+ /// The field whose default is being used.
FieldDecl *Field;
- /// \brief The location where the default initializer expression was used.
+ /// The location where the default initializer expression was used.
SourceLocation Loc;
CXXDefaultInitExpr(const ASTContext &C, SourceLocation Loc, FieldDecl *Field,
@@ -1133,11 +1134,11 @@ public:
return new (C) CXXDefaultInitExpr(C, Loc, Field, Field->getType());
}
- /// \brief Get the field whose initializer will be used.
+ /// Get the field whose initializer will be used.
FieldDecl *getField() { return Field; }
const FieldDecl *getField() const { return Field; }
- /// \brief Get the initialization expression that will be used.
+ /// Get the initialization expression that will be used.
const Expr *getExpr() const {
assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
return Field->getInClassInitializer();
@@ -1160,9 +1161,9 @@ public:
}
};
-/// \brief Represents a C++ temporary.
+/// Represents a C++ temporary.
class CXXTemporary {
- /// \brief The destructor that needs to be called.
+ /// The destructor that needs to be called.
const CXXDestructorDecl *Destructor;
explicit CXXTemporary(const CXXDestructorDecl *destructor)
@@ -1179,7 +1180,7 @@ public:
}
};
-/// \brief Represents binding an expression to a temporary.
+/// Represents binding an expression to a temporary.
///
/// This ensures the destructor is called for the temporary. It should only be
/// needed for non-POD, non-trivially destructable class types. For example:
@@ -1235,7 +1236,7 @@ public:
child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
};
-/// \brief Represents a call to a C++ constructor.
+/// Represents a call to a C++ constructor.
class CXXConstructExpr : public Expr {
public:
enum ConstructionKind {
@@ -1273,7 +1274,7 @@ protected:
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
- /// \brief Construct an empty C++ construction expression.
+ /// Construct an empty C++ construction expression.
CXXConstructExpr(StmtClass SC, EmptyShell Empty)
: Expr(SC, Empty), NumArgs(0), Elidable(false),
HadMultipleCandidates(false), ListInitialization(false),
@@ -1282,7 +1283,7 @@ protected:
public:
friend class ASTStmtReader;
- /// \brief Construct an empty C++ construction expression.
+ /// Construct an empty C++ construction expression.
explicit CXXConstructExpr(EmptyShell Empty)
: CXXConstructExpr(CXXConstructExprClass, Empty) {}
@@ -1298,40 +1299,40 @@ public:
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
- /// \brief Get the constructor that this expression will (ultimately) call.
+ /// Get the constructor that this expression will (ultimately) call.
CXXConstructorDecl *getConstructor() const { return Constructor; }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation Loc) { this->Loc = Loc; }
- /// \brief Whether this construction is elidable.
+ /// Whether this construction is elidable.
bool isElidable() const { return Elidable; }
void setElidable(bool E) { Elidable = E; }
- /// \brief Whether the referred constructor was resolved from
+ /// Whether the referred constructor was resolved from
/// an overloaded set having size greater than 1.
bool hadMultipleCandidates() const { return HadMultipleCandidates; }
void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
- /// \brief Whether this constructor call was written as list-initialization.
+ /// Whether this constructor call was written as list-initialization.
bool isListInitialization() const { return ListInitialization; }
void setListInitialization(bool V) { ListInitialization = V; }
- /// \brief Whether this constructor call was written as list-initialization,
+ /// 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
+ /// Whether this construction first requires
/// zero-initialization before the initializer is called.
bool requiresZeroInitialization() const { return ZeroInitialization; }
void setRequiresZeroInitialization(bool ZeroInit) {
ZeroInitialization = ZeroInit;
}
- /// \brief Determine whether this constructor is actually constructing
+ /// Determine whether this constructor is actually constructing
/// a base class (rather than a complete object).
ConstructionKind getConstructionKind() const {
return (ConstructionKind)ConstructKind;
@@ -1361,7 +1362,7 @@ public:
}
unsigned getNumArgs() const { return NumArgs; }
- /// \brief Return the specified argument.
+ /// Return the specified argument.
Expr *getArg(unsigned Arg) {
assert(Arg < NumArgs && "Arg access out of range!");
return cast<Expr>(Args[Arg]);
@@ -1371,7 +1372,7 @@ public:
return cast<Expr>(Args[Arg]);
}
- /// \brief Set the specified argument.
+ /// Set the specified argument.
void setArg(unsigned Arg, Expr *ArgExpr) {
assert(Arg < NumArgs && "Arg access out of range!");
Args[Arg] = ArgExpr;
@@ -1393,7 +1394,7 @@ public:
}
};
-/// \brief Represents a call to an inherited base class constructor from an
+/// Represents a call to an inherited base class constructor from an
/// inheriting constructor. This call implicitly forwards the arguments from
/// the enclosing context (an inheriting constructor) to the specified inherited
/// base class constructor.
@@ -1414,7 +1415,7 @@ private:
public:
friend class ASTStmtReader;
- /// \brief Construct a C++ inheriting construction expression.
+ /// Construct a C++ inheriting construction expression.
CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T,
CXXConstructorDecl *Ctor, bool ConstructsVirtualBase,
bool InheritedFromVirtualBase)
@@ -1426,15 +1427,15 @@ public:
assert(!T->isDependentType());
}
- /// \brief Construct an empty C++ inheriting construction expression.
+ /// Construct an empty C++ inheriting construction expression.
explicit CXXInheritedCtorInitExpr(EmptyShell Empty)
: Expr(CXXInheritedCtorInitExprClass, Empty),
ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {}
- /// \brief Get the constructor that this expression will call.
+ /// Get the constructor that this expression will call.
CXXConstructorDecl *getConstructor() const { return Constructor; }
- /// \brief Determine whether this constructor is actually constructing
+ /// Determine whether this constructor is actually constructing
/// a base class (rather than a complete object).
bool constructsVBase() const { return ConstructsVirtualBase; }
CXXConstructExpr::ConstructionKind getConstructionKind() const {
@@ -1442,7 +1443,7 @@ public:
: CXXConstructExpr::CK_NonVirtualBase;
}
- /// \brief Determine whether the inherited constructor is inherited from a
+ /// Determine whether the inherited constructor is inherited from a
/// virtual base of the object we construct. If so, we are not responsible
/// for calling the inherited constructor (the complete object constructor
/// does that), and so we don't need to pass any arguments.
@@ -1461,7 +1462,7 @@ public:
}
};
-/// \brief Represents an explicit C++ type conversion that uses "functional"
+/// Represents an explicit C++ type conversion that uses "functional"
/// notation (C++ [expr.type.conv]).
///
/// Example:
@@ -1504,6 +1505,9 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+ /// Determine whether this expression models list-initialization.
+ bool isListInitialization() const { return LParenLoc.isInvalid(); }
+
SourceLocation getLocStart() const LLVM_READONLY;
SourceLocation getLocEnd() const LLVM_READONLY;
@@ -1512,7 +1516,7 @@ public:
}
};
-/// @brief Represents a C++ functional cast expression that builds a
+/// Represents a C++ functional cast expression that builds a
/// temporary object.
///
/// This expression type represents a C++ "functional" cast
@@ -1556,7 +1560,7 @@ public:
}
};
-/// \brief A C++ lambda expression, which produces a function object
+/// A C++ lambda expression, which produces a function object
/// (of unspecified type) that can be invoked later.
///
/// Example:
@@ -1579,27 +1583,27 @@ public:
/// and which can never occur implicitly.
class LambdaExpr final : public Expr,
private llvm::TrailingObjects<LambdaExpr, Stmt *> {
- /// \brief The source range that covers the lambda introducer ([...]).
+ /// The source range that covers the lambda introducer ([...]).
SourceRange IntroducerRange;
- /// \brief The source location of this lambda's capture-default ('=' or '&').
+ /// The source location of this lambda's capture-default ('=' or '&').
SourceLocation CaptureDefaultLoc;
- /// \brief The number of captures.
+ /// The number of captures.
unsigned NumCaptures : 16;
- /// \brief The default capture kind, which is a value of type
+ /// The default capture kind, which is a value of type
/// LambdaCaptureDefault.
unsigned CaptureDefault : 2;
- /// \brief Whether this lambda had an explicit parameter list vs. an
+ /// Whether this lambda had an explicit parameter list vs. an
/// implicit (and empty) parameter list.
unsigned ExplicitParams : 1;
- /// \brief Whether this lambda had the result type explicitly specified.
+ /// Whether this lambda had the result type explicitly specified.
unsigned ExplicitResultType : 1;
- /// \brief The location of the closing brace ('}') that completes
+ /// The location of the closing brace ('}') that completes
/// the lambda.
///
/// The location of the brace is also available by looking up the
@@ -1609,7 +1613,7 @@ class LambdaExpr final : public Expr,
/// module file just to determine the source range.
SourceLocation ClosingBrace;
- /// \brief Construct a lambda expression.
+ /// Construct a lambda expression.
LambdaExpr(QualType T, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
@@ -1617,7 +1621,7 @@ class LambdaExpr final : public Expr,
ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace,
bool ContainsUnexpandedParameterPack);
- /// \brief Construct an empty lambda expression.
+ /// Construct an empty lambda expression.
LambdaExpr(EmptyShell Empty, unsigned NumCaptures)
: Expr(LambdaExprClass, Empty), NumCaptures(NumCaptures),
CaptureDefault(LCD_None), ExplicitParams(false),
@@ -1634,7 +1638,7 @@ public:
friend class ASTStmtWriter;
friend TrailingObjects;
- /// \brief Construct a new lambda expression.
+ /// Construct a new lambda expression.
static LambdaExpr *
Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc,
@@ -1642,143 +1646,143 @@ public:
bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack);
- /// \brief Construct a new lambda expression that will be deserialized from
+ /// Construct a new lambda expression that will be deserialized from
/// an external source.
static LambdaExpr *CreateDeserialized(const ASTContext &C,
unsigned NumCaptures);
- /// \brief Determine the default capture kind for this lambda.
+ /// Determine the default capture kind for this lambda.
LambdaCaptureDefault getCaptureDefault() const {
return static_cast<LambdaCaptureDefault>(CaptureDefault);
}
- /// \brief Retrieve the location of this lambda's capture-default, if any.
+ /// Retrieve the location of this lambda's capture-default, if any.
SourceLocation getCaptureDefaultLoc() const {
return CaptureDefaultLoc;
}
- /// \brief Determine whether one of this lambda's captures is an init-capture.
+ /// Determine whether one of this lambda's captures is an init-capture.
bool isInitCapture(const LambdaCapture *Capture) const;
- /// \brief An iterator that walks over the captures of the lambda,
+ /// An iterator that walks over the captures of the lambda,
/// both implicit and explicit.
using capture_iterator = const LambdaCapture *;
- /// \brief An iterator over a range of lambda captures.
+ /// An iterator over a range of lambda captures.
using capture_range = llvm::iterator_range<capture_iterator>;
- /// \brief Retrieve this lambda's captures.
+ /// Retrieve this lambda's captures.
capture_range captures() const;
- /// \brief Retrieve an iterator pointing to the first lambda capture.
+ /// Retrieve an iterator pointing to the first lambda capture.
capture_iterator capture_begin() const;
- /// \brief Retrieve an iterator pointing past the end of the
+ /// Retrieve an iterator pointing past the end of the
/// sequence of lambda captures.
capture_iterator capture_end() const;
- /// \brief Determine the number of captures in this lambda.
+ /// Determine the number of captures in this lambda.
unsigned capture_size() const { return NumCaptures; }
- /// \brief Retrieve this lambda's explicit captures.
+ /// Retrieve this lambda's explicit captures.
capture_range explicit_captures() const;
- /// \brief Retrieve an iterator pointing to the first explicit
+ /// Retrieve an iterator pointing to the first explicit
/// lambda capture.
capture_iterator explicit_capture_begin() const;
- /// \brief Retrieve an iterator pointing past the end of the sequence of
+ /// Retrieve an iterator pointing past the end of the sequence of
/// explicit lambda captures.
capture_iterator explicit_capture_end() const;
- /// \brief Retrieve this lambda's implicit captures.
+ /// Retrieve this lambda's implicit captures.
capture_range implicit_captures() const;
- /// \brief Retrieve an iterator pointing to the first implicit
+ /// Retrieve an iterator pointing to the first implicit
/// lambda capture.
capture_iterator implicit_capture_begin() const;
- /// \brief Retrieve an iterator pointing past the end of the sequence of
+ /// Retrieve an iterator pointing past the end of the sequence of
/// implicit lambda captures.
capture_iterator implicit_capture_end() const;
- /// \brief Iterator that walks over the capture initialization
+ /// Iterator that walks over the capture initialization
/// arguments.
using capture_init_iterator = Expr **;
- /// \brief Const iterator that walks over the capture initialization
+ /// Const iterator that walks over the capture initialization
/// arguments.
using const_capture_init_iterator = Expr *const *;
- /// \brief Retrieve the initialization expressions for this lambda's captures.
+ /// Retrieve the initialization expressions for this lambda's captures.
llvm::iterator_range<capture_init_iterator> capture_inits() {
return llvm::make_range(capture_init_begin(), capture_init_end());
}
- /// \brief Retrieve the initialization expressions for this lambda's captures.
+ /// Retrieve the initialization expressions for this lambda's captures.
llvm::iterator_range<const_capture_init_iterator> capture_inits() const {
return llvm::make_range(capture_init_begin(), capture_init_end());
}
- /// \brief Retrieve the first initialization argument for this
+ /// Retrieve the first initialization argument for this
/// lambda expression (which initializes the first capture field).
capture_init_iterator capture_init_begin() {
return reinterpret_cast<Expr **>(getStoredStmts());
}
- /// \brief Retrieve the first initialization argument for this
+ /// Retrieve the first initialization argument for this
/// lambda expression (which initializes the first capture field).
const_capture_init_iterator capture_init_begin() const {
return reinterpret_cast<Expr *const *>(getStoredStmts());
}
- /// \brief Retrieve the iterator pointing one past the last
+ /// Retrieve the iterator pointing one past the last
/// initialization argument for this lambda expression.
capture_init_iterator capture_init_end() {
return capture_init_begin() + NumCaptures;
}
- /// \brief Retrieve the iterator pointing one past the last
+ /// Retrieve the iterator pointing one past the last
/// initialization argument for this lambda expression.
const_capture_init_iterator capture_init_end() const {
return capture_init_begin() + NumCaptures;
}
- /// \brief Retrieve the source range covering the lambda introducer,
+ /// Retrieve the source range covering the lambda introducer,
/// which contains the explicit capture list surrounded by square
/// brackets ([...]).
SourceRange getIntroducerRange() const { return IntroducerRange; }
- /// \brief Retrieve the class that corresponds to the lambda.
+ /// Retrieve the class that corresponds to the lambda.
///
/// This is the "closure type" (C++1y [expr.prim.lambda]), and stores the
/// captures in its fields and provides the various operations permitted
/// on a lambda (copying, calling).
CXXRecordDecl *getLambdaClass() const;
- /// \brief Retrieve the function call operator associated with this
+ /// Retrieve the function call operator associated with this
/// lambda expression.
CXXMethodDecl *getCallOperator() const;
- /// \brief If this is a generic lambda expression, retrieve the template
+ /// If this is a generic lambda expression, retrieve the template
/// parameter list associated with it, or else return null.
TemplateParameterList *getTemplateParameterList() const;
- /// \brief Whether this is a generic lambda.
+ /// Whether this is a generic lambda.
bool isGenericLambda() const { return getTemplateParameterList(); }
- /// \brief Retrieve the body of the lambda.
+ /// Retrieve the body of the lambda.
CompoundStmt *getBody() const;
- /// \brief Determine whether the lambda is mutable, meaning that any
+ /// Determine whether the lambda is mutable, meaning that any
/// captures values can be modified.
bool isMutable() const;
- /// \brief Determine whether this lambda has an explicit parameter
+ /// Determine whether this lambda has an explicit parameter
/// list vs. an implicit (empty) parameter list.
bool hasExplicitParameters() const { return ExplicitParams; }
- /// \brief Whether this lambda had its result type explicitly specified.
+ /// Whether this lambda had its result type explicitly specified.
bool hasExplicitResultType() const { return ExplicitResultType; }
static bool classof(const Stmt *T) {
@@ -1806,7 +1810,7 @@ class CXXScalarValueInitExpr : public Expr {
TypeSourceInfo *TypeInfo;
public:
- /// \brief Create an explicitly-written scalar-value initialization
+ /// Create an explicitly-written scalar-value initialization
/// expression.
CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
SourceLocation rParenLoc)
@@ -1837,7 +1841,7 @@ public:
}
};
-/// \brief Represents a new-expression for memory allocation and constructor
+/// Represents a new-expression for memory allocation and constructor
/// calls, e.g: "new CXXNewExpr(foo)".
class CXXNewExpr : public Expr {
friend class ASTStmtReader;
@@ -1847,24 +1851,24 @@ class CXXNewExpr : public Expr {
/// expression, and any number of optional placement arguments, in that order.
Stmt **SubExprs = nullptr;
- /// \brief Points to the allocation function used.
+ /// Points to the allocation function used.
FunctionDecl *OperatorNew;
- /// \brief Points to the deallocation function used in case of error. May be
+ /// Points to the deallocation function used in case of error. May be
/// null.
FunctionDecl *OperatorDelete;
- /// \brief The allocated type-source information, as written in the source.
+ /// The allocated type-source information, as written in the source.
TypeSourceInfo *AllocatedTypeInfo;
- /// \brief If the allocated type was expressed as a parenthesized type-id,
+ /// If the allocated type was expressed as a parenthesized type-id,
/// the source range covering the parenthesized type-id.
SourceRange TypeIdParens;
- /// \brief Range of the entire new expression.
+ /// Range of the entire new expression.
SourceRange Range;
- /// \brief Source-range of a paren-delimited initializer.
+ /// Source-range of a paren-delimited initializer.
SourceRange DirectInitRange;
/// Was the usage ::new, i.e. is the global new to be used?
@@ -1922,7 +1926,7 @@ public:
return AllocatedTypeInfo;
}
- /// \brief True if the allocation result needs to be null-checked.
+ /// True if the allocation result needs to be null-checked.
///
/// C++11 [expr.new]p13:
/// If the allocation function returns null, initialization shall
@@ -1973,17 +1977,17 @@ public:
bool isGlobalNew() const { return GlobalNew; }
- /// \brief Whether this new-expression has any initializer at all.
+ /// Whether this new-expression has any initializer at all.
bool hasInitializer() const { return StoredInitializationStyle > 0; }
- /// \brief The kind of initializer this new-expression has.
+ /// The kind of initializer this new-expression has.
InitializationStyle getInitializationStyle() const {
if (StoredInitializationStyle == 0)
return NoInit;
return static_cast<InitializationStyle>(StoredInitializationStyle-1);
}
- /// \brief The initializer of this new-expression.
+ /// The initializer of this new-expression.
Expr *getInitializer() {
return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
}
@@ -1991,7 +1995,7 @@ public:
return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
}
- /// \brief Returns the CXXConstructExpr from this new-expression, or null.
+ /// Returns the CXXConstructExpr from this new-expression, or null.
const CXXConstructExpr *getConstructExpr() const {
return dyn_cast_or_null<CXXConstructExpr>(getInitializer());
}
@@ -2066,7 +2070,7 @@ public:
}
};
-/// \brief Represents a \c delete expression for memory deallocation and
+/// Represents a \c delete expression for memory deallocation and
/// destructor calls, e.g. "delete[] pArray".
class CXXDeleteExpr : public Expr {
/// Points to the operator delete overload that is used. Could be a member.
@@ -2125,7 +2129,7 @@ public:
Expr *getArgument() { return cast<Expr>(Argument); }
const Expr *getArgument() const { return cast<Expr>(Argument); }
- /// \brief Retrieve the type being destroyed.
+ /// Retrieve the type being destroyed.
///
/// If the type being destroyed is a dependent type which may or may not
/// be a pointer, return an invalid type.
@@ -2142,13 +2146,13 @@ public:
child_range children() { return child_range(&Argument, &Argument+1); }
};
-/// \brief Stores the type being destroyed by a pseudo-destructor expression.
+/// Stores the type being destroyed by a pseudo-destructor expression.
class PseudoDestructorTypeStorage {
- /// \brief Either the type source information or the name of the type, if
+ /// Either the type source information or the name of the type, if
/// it couldn't be resolved due to type-dependence.
llvm::PointerUnion<TypeSourceInfo *, IdentifierInfo *> Type;
- /// \brief The starting source location of the pseudo-destructor type.
+ /// The starting source location of the pseudo-destructor type.
SourceLocation Location;
public:
@@ -2170,7 +2174,7 @@ public:
SourceLocation getLocation() const { return Location; }
};
-/// \brief Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
+/// Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
///
/// A pseudo-destructor is an expression that looks like a member access to a
/// destructor of a scalar type, except that scalar types don't have
@@ -2197,31 +2201,31 @@ public:
class CXXPseudoDestructorExpr : public Expr {
friend class ASTStmtReader;
- /// \brief The base expression (that is being destroyed).
+ /// The base expression (that is being destroyed).
Stmt *Base = nullptr;
- /// \brief Whether the operator was an arrow ('->'); otherwise, it was a
+ /// Whether the operator was an arrow ('->'); otherwise, it was a
/// period ('.').
bool IsArrow : 1;
- /// \brief The location of the '.' or '->' operator.
+ /// The location of the '.' or '->' operator.
SourceLocation OperatorLoc;
- /// \brief The nested-name-specifier that follows the operator, if present.
+ /// The nested-name-specifier that follows the operator, if present.
NestedNameSpecifierLoc QualifierLoc;
- /// \brief The type that precedes the '::' in a qualified pseudo-destructor
+ /// The type that precedes the '::' in a qualified pseudo-destructor
/// expression.
TypeSourceInfo *ScopeType = nullptr;
- /// \brief The location of the '::' in a qualified pseudo-destructor
+ /// The location of the '::' in a qualified pseudo-destructor
/// expression.
SourceLocation ColonColonLoc;
- /// \brief The location of the '~'.
+ /// The location of the '~'.
SourceLocation TildeLoc;
- /// \brief The type being destroyed, or its name if we were unable to
+ /// The type being destroyed, or its name if we were unable to
/// resolve the name.
PseudoDestructorTypeStorage DestroyedType;
@@ -2239,30 +2243,30 @@ public:
Expr *getBase() const { return cast<Expr>(Base); }
- /// \brief Determines whether this member expression actually had
+ /// 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 QualifierLoc.hasQualifier(); }
- /// \brief Retrieves the nested-name-specifier that qualifies the type name,
+ /// Retrieves the nested-name-specifier that qualifies the type name,
/// with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// \brief If the member name was qualified, retrieves the
+ /// If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name. Otherwise, returns
/// null.
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
- /// \brief Determine whether this pseudo-destructor expression was written
+ /// Determine whether this pseudo-destructor expression was written
/// using an '->' (otherwise, it used a '.').
bool isArrow() const { return IsArrow; }
- /// \brief Retrieve the location of the '.' or '->' operator.
+ /// Retrieve the location of the '.' or '->' operator.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
- /// \brief Retrieve the scope type in a qualified pseudo-destructor
+ /// Retrieve the scope type in a qualified pseudo-destructor
/// expression.
///
/// Pseudo-destructor expressions can have extra qualification within them
@@ -2273,14 +2277,14 @@ public:
/// destructor expression.
TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
- /// \brief Retrieve the location of the '::' in a qualified pseudo-destructor
+ /// Retrieve the location of the '::' in a qualified pseudo-destructor
/// expression.
SourceLocation getColonColonLoc() const { return ColonColonLoc; }
- /// \brief Retrieve the location of the '~'.
+ /// Retrieve the location of the '~'.
SourceLocation getTildeLoc() const { return TildeLoc; }
- /// \brief Retrieve the source location information for the type
+ /// Retrieve the source location information for the type
/// being destroyed.
///
/// This type-source information is available for non-dependent
@@ -2291,28 +2295,28 @@ public:
return DestroyedType.getTypeSourceInfo();
}
- /// \brief In a dependent pseudo-destructor expression for which we do not
+ /// In a dependent pseudo-destructor expression for which we do not
/// have full type information on the destroyed type, provides the name
/// of the destroyed type.
IdentifierInfo *getDestroyedTypeIdentifier() const {
return DestroyedType.getIdentifier();
}
- /// \brief Retrieve the type being destroyed.
+ /// Retrieve the type being destroyed.
QualType getDestroyedType() const;
- /// \brief Retrieve the starting location of the type being destroyed.
+ /// Retrieve the starting location of the type being destroyed.
SourceLocation getDestroyedTypeLoc() const {
return DestroyedType.getLocation();
}
- /// \brief Set the name of destroyed type for a dependent pseudo-destructor
+ /// Set the name of destroyed type for a dependent pseudo-destructor
/// expression.
void setDestroyedType(IdentifierInfo *II, SourceLocation Loc) {
DestroyedType = PseudoDestructorTypeStorage(II, Loc);
}
- /// \brief Set the destroyed type.
+ /// Set the destroyed type.
void setDestroyedType(TypeSourceInfo *Info) {
DestroyedType = PseudoDestructorTypeStorage(Info);
}
@@ -2328,7 +2332,7 @@ public:
child_range children() { return child_range(&Base, &Base + 1); }
};
-/// \brief A type trait used in the implementation of various C++11 and
+/// A type trait used in the implementation of various C++11 and
/// Library TR1 trait templates.
///
/// \code
@@ -2339,10 +2343,10 @@ public:
class TypeTraitExpr final
: public Expr,
private llvm::TrailingObjects<TypeTraitExpr, TypeSourceInfo *> {
- /// \brief The location of the type trait keyword.
+ /// The location of the type trait keyword.
SourceLocation Loc;
- /// \brief The location of the closing parenthesis.
+ /// The location of the closing parenthesis.
SourceLocation RParenLoc;
// Note: The TypeSourceInfos for the arguments are allocated after the
@@ -2364,7 +2368,7 @@ public:
friend class ASTStmtWriter;
friend TrailingObjects;
- /// \brief Create a new type trait expression.
+ /// Create a new type trait expression.
static TypeTraitExpr *Create(const ASTContext &C, QualType T,
SourceLocation Loc, TypeTrait Kind,
ArrayRef<TypeSourceInfo *> Args,
@@ -2374,7 +2378,7 @@ public:
static TypeTraitExpr *CreateDeserialized(const ASTContext &C,
unsigned NumArgs);
- /// \brief Determine which type trait this expression uses.
+ /// Determine which type trait this expression uses.
TypeTrait getTrait() const {
return static_cast<TypeTrait>(TypeTraitExprBits.Kind);
}
@@ -2384,16 +2388,16 @@ public:
return TypeTraitExprBits.Value;
}
- /// \brief Determine the number of arguments to this type trait.
+ /// Determine the number of arguments to this type trait.
unsigned getNumArgs() const { return TypeTraitExprBits.NumArgs; }
- /// \brief Retrieve the Ith argument.
+ /// Retrieve the Ith argument.
TypeSourceInfo *getArg(unsigned I) const {
assert(I < getNumArgs() && "Argument out-of-range");
return getArgs()[I];
}
- /// \brief Retrieve the argument types.
+ /// Retrieve the argument types.
ArrayRef<TypeSourceInfo *> getArgs() const {
return llvm::makeArrayRef(getTrailingObjects<TypeSourceInfo *>(),
getNumArgs());
@@ -2412,7 +2416,7 @@ public:
}
};
-/// \brief An Embarcadero array type trait, as used in the implementation of
+/// An Embarcadero array type trait, as used in the implementation of
/// __array_rank and __array_extent.
///
/// Example:
@@ -2421,22 +2425,22 @@ public:
/// __array_extent(int, 1) == 20
/// \endcode
class ArrayTypeTraitExpr : public Expr {
- /// \brief The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
+ /// The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
unsigned ATT : 2;
- /// \brief The value of the type trait. Unspecified if dependent.
+ /// The value of the type trait. Unspecified if dependent.
uint64_t Value = 0;
- /// \brief The array dimension being queried, or -1 if not used.
+ /// The array dimension being queried, or -1 if not used.
Expr *Dimension;
- /// \brief The location of the type trait keyword.
+ /// The location of the type trait keyword.
SourceLocation Loc;
- /// \brief The location of the closing paren.
+ /// The location of the closing paren.
SourceLocation RParen;
- /// \brief The type being queried.
+ /// The type being queried.
TypeSourceInfo *QueriedType = nullptr;
virtual void anchor();
@@ -2483,7 +2487,7 @@ public:
}
};
-/// \brief An expression trait intrinsic.
+/// An expression trait intrinsic.
///
/// Example:
/// \code
@@ -2491,19 +2495,19 @@ public:
/// __is_lvalue_expr(1) == false
/// \endcode
class ExpressionTraitExpr : public Expr {
- /// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned.
+ /// The trait. A ExpressionTrait enum in MSVC compatible unsigned.
unsigned ET : 31;
- /// \brief The value of the type trait. Unspecified if dependent.
+ /// The value of the type trait. Unspecified if dependent.
unsigned Value : 1;
- /// \brief The location of the type trait keyword.
+ /// The location of the type trait keyword.
SourceLocation Loc;
- /// \brief The location of the closing paren.
+ /// The location of the closing paren.
SourceLocation RParen;
- /// \brief The expression being queried.
+ /// The expression being queried.
Expr* QueriedExpression = nullptr;
public:
@@ -2543,13 +2547,13 @@ public:
}
};
-/// \brief A reference to an overloaded function set, either an
+/// A reference to an overloaded function set, either an
/// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr.
class OverloadExpr : public Expr {
- /// \brief The common name of these declarations.
+ /// The common name of these declarations.
DeclarationNameInfo NameInfo;
- /// \brief The nested-name-specifier that qualifies the name, if any.
+ /// The nested-name-specifier that qualifies the name, if any.
NestedNameSpecifierLoc QualifierLoc;
/// The results. These are undesugared, which is to say, they may
@@ -2561,7 +2565,7 @@ class OverloadExpr : public Expr {
unsigned NumResults = 0;
protected:
- /// \brief Whether the name includes info for explicit template
+ /// Whether the name includes info for explicit template
/// keyword and arguments.
bool HasTemplateKWAndArgsInfo = false;
@@ -2577,11 +2581,11 @@ protected:
OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty) {}
- /// \brief Return the optional template keyword and arguments info.
+ /// Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *
getTrailingASTTemplateKWAndArgsInfo(); // defined far below.
- /// \brief Return the optional template keyword and arguments info.
+ /// Return the optional template keyword and arguments info.
const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const {
return const_cast<OverloadExpr *>(this)
->getTrailingASTTemplateKWAndArgsInfo();
@@ -2604,7 +2608,7 @@ public:
bool HasFormOfMemberPointer;
};
- /// \brief Finds the overloaded expression in the given expression \p E of
+ /// Finds the overloaded expression in the given expression \p E of
/// OverloadTy.
///
/// \return the expression (which must be there) and true if it has
@@ -2618,7 +2622,7 @@ public:
if (isa<UnaryOperator>(E)) {
assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf);
E = cast<UnaryOperator>(E)->getSubExpr();
- OverloadExpr *Ovl = cast<OverloadExpr>(E->IgnoreParens());
+ auto *Ovl = cast<OverloadExpr>(E->IgnoreParens());
Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier());
Result.IsAddressOfOperand = true;
@@ -2632,7 +2636,7 @@ public:
return Result;
}
- /// \brief Gets the naming class of this lookup, if any.
+ /// Gets the naming class of this lookup, if any.
CXXRecordDecl *getNamingClass() const;
using decls_iterator = UnresolvedSetImpl::iterator;
@@ -2645,52 +2649,52 @@ public:
return llvm::make_range(decls_begin(), decls_end());
}
- /// \brief Gets the number of declarations in the unresolved set.
+ /// Gets the number of declarations in the unresolved set.
unsigned getNumDecls() const { return NumResults; }
- /// \brief Gets the full name info.
+ /// Gets the full name info.
const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
- /// \brief Gets the name looked up.
+ /// Gets the name looked up.
DeclarationName getName() const { return NameInfo.getName(); }
- /// \brief Gets the location of the name.
+ /// Gets the location of the name.
SourceLocation getNameLoc() const { return NameInfo.getLoc(); }
- /// \brief Fetches the nested-name qualifier, if one was given.
+ /// Fetches the nested-name qualifier, if one was given.
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
- /// \brief Fetches the nested-name qualifier with source-location
+ /// Fetches the nested-name qualifier with source-location
/// information, if one was given.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// \brief Retrieve the location of the template keyword preceding
+ /// Retrieve the location of the template keyword preceding
/// this name, if any.
SourceLocation getTemplateKeywordLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc;
}
- /// \brief Retrieve the location of the left angle bracket starting the
+ /// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the name, if any.
SourceLocation getLAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc;
}
- /// \brief Retrieve the location of the right angle bracket ending the
+ /// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the name, if any.
SourceLocation getRAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc;
}
- /// \brief Determines whether the name was preceded by the template keyword.
+ /// Determines whether the name was preceded by the template keyword.
bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
- /// \brief Determines whether this expression had explicit template arguments.
+ /// Determines whether this expression had explicit template arguments.
bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
TemplateArgumentLoc const *getTemplateArgs() const {
@@ -2710,7 +2714,7 @@ public:
return {getTemplateArgs(), getNumTemplateArgs()};
}
- /// \brief Copies the template arguments into the given structure.
+ /// Copies the template arguments into the given structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgs())
getTrailingASTTemplateKWAndArgsInfo()->copyInto(getTemplateArgs(), List);
@@ -2722,7 +2726,7 @@ public:
}
};
-/// \brief A reference to a name which we were able to look up during
+/// A reference to a name which we were able to look up during
/// parsing but could not resolve to a specific declaration.
///
/// This arises in several ways:
@@ -2837,7 +2841,7 @@ public:
}
};
-/// \brief A qualified reference to a name whose declaration cannot
+/// A qualified reference to a name whose declaration cannot
/// yet be resolved.
///
/// DependentScopeDeclRefExpr is similar to DeclRefExpr in that
@@ -2856,14 +2860,14 @@ class DependentScopeDeclRefExpr final
private llvm::TrailingObjects<DependentScopeDeclRefExpr,
ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
- /// \brief The nested-name-specifier that qualifies this unresolved
+ /// The nested-name-specifier that qualifies this unresolved
/// declaration name.
NestedNameSpecifierLoc QualifierLoc;
- /// \brief The name of the entity we will be referencing.
+ /// The name of the entity we will be referencing.
DeclarationNameInfo NameInfo;
- /// \brief Whether the name includes info for explicit template
+ /// Whether the name includes info for explicit template
/// keyword and arguments.
bool HasTemplateKWAndArgsInfo;
@@ -2892,42 +2896,42 @@ public:
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);
- /// \brief Retrieve the name that this expression refers to.
+ /// Retrieve the name that this expression refers to.
const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
- /// \brief Retrieve the name that this expression refers to.
+ /// Retrieve the name that this expression refers to.
DeclarationName getDeclName() const { return NameInfo.getName(); }
- /// \brief Retrieve the location of the name within the expression.
+ /// Retrieve the location of the name within the expression.
///
/// For example, in "X<T>::value" this is the location of "value".
SourceLocation getLocation() const { return NameInfo.getLoc(); }
- /// \brief Retrieve the nested-name-specifier that qualifies the
+ /// Retrieve the nested-name-specifier that qualifies the
/// name, with source location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// \brief Retrieve the nested-name-specifier that qualifies this
+ /// Retrieve the nested-name-specifier that qualifies this
/// declaration.
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
- /// \brief Retrieve the location of the template keyword preceding
+ /// Retrieve the location of the template keyword preceding
/// this name, if any.
SourceLocation getTemplateKeywordLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
}
- /// \brief Retrieve the location of the left angle bracket starting the
+ /// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the name, if any.
SourceLocation getLAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
}
- /// \brief Retrieve the location of the right angle bracket ending the
+ /// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the name, if any.
SourceLocation getRAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
@@ -2940,7 +2944,7 @@ public:
/// Determines whether this lookup had explicit template arguments.
bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
- /// \brief Copies the template arguments (if present) into the given
+ /// Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgs())
@@ -3063,7 +3067,7 @@ public:
child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
};
-/// \brief Describes an explicit type conversion that uses functional
+/// Describes an explicit type conversion that uses functional
/// notion but could not be resolved because one or more arguments are
/// type-dependent.
///
@@ -3090,16 +3094,16 @@ class CXXUnresolvedConstructExpr final
friend class ASTStmtReader;
friend TrailingObjects;
- /// \brief The type being constructed.
+ /// The type being constructed.
TypeSourceInfo *Type = nullptr;
- /// \brief The location of the left parentheses ('(').
+ /// The location of the left parentheses ('(').
SourceLocation LParenLoc;
- /// \brief The location of the right parentheses (')').
+ /// The location of the right parentheses (')').
SourceLocation RParenLoc;
- /// \brief The number of arguments used to construct the type.
+ /// The number of arguments used to construct the type.
unsigned NumArgs;
CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
@@ -3120,20 +3124,20 @@ public:
static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &C,
unsigned NumArgs);
- /// \brief Retrieve the type that is being constructed, as specified
+ /// Retrieve the type that is being constructed, as specified
/// in the source code.
QualType getTypeAsWritten() const { return Type->getType(); }
- /// \brief Retrieve the type source information for the type being
+ /// Retrieve the type source information for the type being
/// constructed.
TypeSourceInfo *getTypeSourceInfo() const { return Type; }
- /// \brief Retrieve the location of the left parentheses ('(') that
+ /// Retrieve the location of the left parentheses ('(') that
/// precedes the argument list.
SourceLocation getLParenLoc() const { return LParenLoc; }
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- /// \brief Retrieve the location of the right parentheses (')') that
+ /// Retrieve the location of the right parentheses (')') that
/// follows the argument list.
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
@@ -3143,7 +3147,7 @@ public:
/// an InitListExpr.
bool isListInitialization() const { return LParenLoc.isInvalid(); }
- /// \brief Retrieve the number of arguments.
+ /// Retrieve the number of arguments.
unsigned arg_size() const { return NumArgs; }
using arg_iterator = Expr **;
@@ -3187,12 +3191,12 @@ public:
// Iterators
child_range children() {
- Stmt **begin = reinterpret_cast<Stmt **>(arg_begin());
+ auto **begin = reinterpret_cast<Stmt **>(arg_begin());
return child_range(begin, begin + NumArgs);
}
};
-/// \brief Represents a C++ member access expression where the actual
+/// Represents a C++ member access expression where the actual
/// member referenced could not be resolved because the base
/// expression or the member name was dependent.
///
@@ -3204,29 +3208,29 @@ class CXXDependentScopeMemberExpr final
private llvm::TrailingObjects<CXXDependentScopeMemberExpr,
ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
- /// \brief The expression for the base pointer or class reference,
+ /// The expression for the base pointer or class reference,
/// e.g., the \c x in x.f. Can be null in implicit accesses.
Stmt *Base;
- /// \brief The type of the base expression. Never null, even for
+ /// The type of the base expression. Never null, even for
/// implicit accesses.
QualType BaseType;
- /// \brief Whether this member expression used the '->' operator or
+ /// Whether this member expression used the '->' operator or
/// the '.' operator.
bool IsArrow : 1;
- /// \brief Whether this member expression has info for explicit template
+ /// Whether this member expression has info for explicit template
/// keyword and arguments.
bool HasTemplateKWAndArgsInfo : 1;
- /// \brief The location of the '->' or '.' operator.
+ /// The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
- /// \brief The nested-name-specifier that precedes the member name, if any.
+ /// The nested-name-specifier that precedes the member name, if any.
NestedNameSpecifierLoc QualifierLoc;
- /// \brief In a qualified member access expression such as t->Base::f, this
+ /// In a qualified member access expression such as t->Base::f, this
/// member stores the resolves of name lookup in the context of the member
/// access expression, to be used at instantiation time.
///
@@ -3235,7 +3239,7 @@ class CXXDependentScopeMemberExpr final
/// the CXXDependentScopeMemberExpr, to save space in the common case.
NamedDecl *FirstQualifierFoundInScope;
- /// \brief The member to which this member expression refers, which
+ /// The member to which this member expression refers, which
/// can be name, overloaded operator, or destructor.
///
/// FIXME: could also be a template-id
@@ -3277,12 +3281,12 @@ public:
CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);
- /// \brief True if this is an implicit access, i.e. one in which the
+ /// True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
bool isImplicitAccess() const;
- /// \brief Retrieve the base object of this member expressions,
+ /// Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
Expr *getBase() const {
assert(!isImplicitAccess());
@@ -3291,24 +3295,24 @@ public:
QualType getBaseType() const { return BaseType; }
- /// \brief Determine whether this member expression used the '->'
+ /// Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
bool isArrow() const { return IsArrow; }
- /// \brief Retrieve the location of the '->' or '.' operator.
+ /// Retrieve the location of the '->' or '.' operator.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
- /// \brief Retrieve the nested-name-specifier that qualifies the member
+ /// Retrieve the nested-name-specifier that qualifies the member
/// name.
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
- /// \brief Retrieve the nested-name-specifier that qualifies the member
+ /// Retrieve the nested-name-specifier that qualifies the member
/// name, with source location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// \brief Retrieve the first part of the nested-name-specifier that was
+ /// Retrieve the first part of the nested-name-specifier that was
/// found in the scope of the member access expression when the member access
/// was initially parsed.
///
@@ -3323,35 +3327,35 @@ public:
return FirstQualifierFoundInScope;
}
- /// \brief Retrieve the name of the member that this expression
+ /// Retrieve the name of the member that this expression
/// refers to.
const DeclarationNameInfo &getMemberNameInfo() const {
return MemberNameInfo;
}
- /// \brief Retrieve the name of the member that this expression
+ /// Retrieve the name of the member that this expression
/// refers to.
DeclarationName getMember() const { return MemberNameInfo.getName(); }
- // \brief Retrieve the location of the name of the member that this
+ // Retrieve the location of the name of the member that this
// expression refers to.
SourceLocation getMemberLoc() const { return MemberNameInfo.getLoc(); }
- /// \brief Retrieve the location of the template keyword preceding the
+ /// Retrieve the location of the template keyword preceding the
/// member name, if any.
SourceLocation getTemplateKeywordLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
}
- /// \brief Retrieve the location of the left angle bracket starting the
+ /// Retrieve the location of the left angle bracket starting the
/// explicit template argument list following the member name, if any.
SourceLocation getLAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
}
- /// \brief Retrieve the location of the right angle bracket ending the
+ /// Retrieve the location of the right angle bracket ending the
/// explicit template argument list following the member name, if any.
SourceLocation getRAngleLoc() const {
if (!HasTemplateKWAndArgsInfo) return SourceLocation();
@@ -3361,11 +3365,11 @@ public:
/// Determines whether the member name was preceded by the template keyword.
bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
- /// \brief Determines whether this member expression actually had a C++
+ /// Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>.
bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
- /// \brief Copies the template arguments (if present) into the given
+ /// Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgs())
@@ -3373,7 +3377,7 @@ public:
getTrailingObjects<TemplateArgumentLoc>(), List);
}
- /// \brief Retrieve the template arguments provided as part of this
+ /// Retrieve the template arguments provided as part of this
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
@@ -3382,7 +3386,7 @@ public:
return getTrailingObjects<TemplateArgumentLoc>();
}
- /// \brief Retrieve the number of template arguments provided as part of this
+ /// Retrieve the number of template arguments provided as part of this
/// template-id.
unsigned getNumTemplateArgs() const {
if (!hasExplicitTemplateArgs())
@@ -3421,7 +3425,7 @@ public:
}
};
-/// \brief Represents a C++ member access expression for which lookup
+/// Represents a C++ member access expression for which lookup
/// produced a set of overloaded functions.
///
/// The member access may be explicit or implicit:
@@ -3444,24 +3448,24 @@ class UnresolvedMemberExpr final
friend class OverloadExpr;
friend TrailingObjects;
- /// \brief Whether this member expression used the '->' operator or
+ /// Whether this member expression used the '->' operator or
/// the '.' operator.
bool IsArrow : 1;
- /// \brief Whether the lookup results contain an unresolved using
+ /// Whether the lookup results contain an unresolved using
/// declaration.
bool HasUnresolvedUsing : 1;
- /// \brief The expression for the base pointer or class reference,
+ /// The expression for the base pointer or class reference,
/// e.g., the \c x in x.f.
///
/// This can be null if this is an 'unbased' member expression.
Stmt *Base = nullptr;
- /// \brief The type of the base expression; never null.
+ /// The type of the base expression; never null.
QualType BaseType;
- /// \brief The location of the '->' or '.' operator.
+ /// The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing,
@@ -3496,13 +3500,13 @@ public:
CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);
- /// \brief True if this is an implicit access, i.e., one in which the
+ /// True if this is an implicit access, i.e., one in which the
/// member being accessed was not written in the source.
///
/// The source location of the operator is invalid in this case.
bool isImplicitAccess() const;
- /// \brief Retrieve the base object of this member expressions,
+ /// Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
Expr *getBase() {
assert(!isImplicitAccess());
@@ -3515,33 +3519,33 @@ public:
QualType getBaseType() const { return BaseType; }
- /// \brief Determine whether the lookup results contain an unresolved using
+ /// Determine whether the lookup results contain an unresolved using
/// declaration.
bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
- /// \brief Determine whether this member expression used the '->'
+ /// Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
bool isArrow() const { return IsArrow; }
- /// \brief Retrieve the location of the '->' or '.' operator.
+ /// Retrieve the location of the '->' or '.' operator.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
- /// \brief Retrieve the naming class of this lookup.
+ /// Retrieve the naming class of this lookup.
CXXRecordDecl *getNamingClass() const;
- /// \brief Retrieve the full name info for the member that this expression
+ /// Retrieve the full name info for the member that this expression
/// refers to.
const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
- /// \brief Retrieve the name of the member that this expression
+ /// Retrieve the name of the member that this expression
/// refers to.
DeclarationName getMemberName() const { return getName(); }
- // \brief Retrieve the location of the name of the member that this
+ // Retrieve the location of the name of the member that this
// expression refers to.
SourceLocation getMemberLoc() const { return getNameLoc(); }
- // \brief Return the preferred location (the member name) for the arrow when
+ // Return the preferred location (the member name) for the arrow when
// diagnosing a problem with this expression.
SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); }
@@ -3593,7 +3597,7 @@ inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
->getTrailingObjects<TemplateArgumentLoc>();
}
-/// \brief Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
+/// Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
///
/// The noexcept expression tests whether a given expression might throw. Its
/// result is a boolean constant.
@@ -3632,7 +3636,7 @@ public:
child_range children() { return child_range(&Operand, &Operand + 1); }
};
-/// \brief Represents a C++11 pack expansion that produces a sequence of
+/// Represents a C++11 pack expansion that produces a sequence of
/// expressions.
///
/// A pack expansion expression contains a pattern (which itself is an
@@ -3655,7 +3659,7 @@ class PackExpansionExpr : public Expr {
SourceLocation EllipsisLoc;
- /// \brief The number of expansions that will be produced by this pack
+ /// The number of expansions that will be produced by this pack
/// expansion expression, if known.
///
/// When zero, the number of expansions is not known. Otherwise, this value
@@ -3677,17 +3681,17 @@ public:
PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) {}
- /// \brief Retrieve the pattern of the pack expansion.
+ /// Retrieve the pattern of the pack expansion.
Expr *getPattern() { return reinterpret_cast<Expr *>(Pattern); }
- /// \brief Retrieve the pattern of the pack expansion.
+ /// Retrieve the pattern of the pack expansion.
const Expr *getPattern() const { return reinterpret_cast<Expr *>(Pattern); }
- /// \brief Retrieve the location of the ellipsis that describes this pack
+ /// Retrieve the location of the ellipsis that describes this pack
/// expansion.
SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
- /// \brief Determine the number of expansions that will be produced when
+ /// Determine the number of expansions that will be produced when
/// this pack expansion is instantiated, if already known.
Optional<unsigned> getNumExpansions() const {
if (NumExpansions)
@@ -3712,7 +3716,7 @@ public:
}
};
-/// \brief Represents an expression that computes the length of a parameter
+/// Represents an expression that computes the length of a parameter
/// pack.
///
/// \code
@@ -3728,16 +3732,16 @@ class SizeOfPackExpr final
friend class ASTStmtWriter;
friend TrailingObjects;
- /// \brief The location of the \c sizeof keyword.
+ /// The location of the \c sizeof keyword.
SourceLocation OperatorLoc;
- /// \brief The location of the name of the parameter pack.
+ /// The location of the name of the parameter pack.
SourceLocation PackLoc;
- /// \brief The location of the closing parenthesis.
+ /// The location of the closing parenthesis.
SourceLocation RParenLoc;
- /// \brief The length of the parameter pack, if known.
+ /// The length of the parameter pack, if known.
///
/// When this expression is not value-dependent, this is the length of
/// the pack. When the expression was parsed rather than instantiated
@@ -3749,10 +3753,10 @@ class SizeOfPackExpr final
/// and this is the length of that array.
unsigned Length;
- /// \brief The parameter pack.
+ /// The parameter pack.
NamedDecl *Pack = nullptr;
- /// \brief Create an expression that computes the length of
+ /// Create an expression that computes the length of
/// the given parameter pack.
SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack,
SourceLocation PackLoc, SourceLocation RParenLoc,
@@ -3765,11 +3769,11 @@ class SizeOfPackExpr final
Length(Length ? *Length : PartialArgs.size()), Pack(Pack) {
assert((!Length || PartialArgs.empty()) &&
"have partial args for non-dependent sizeof... expression");
- TemplateArgument *Args = getTrailingObjects<TemplateArgument>();
+ auto *Args = getTrailingObjects<TemplateArgument>();
std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args);
}
- /// \brief Create an empty expression.
+ /// Create an empty expression.
SizeOfPackExpr(EmptyShell Empty, unsigned NumPartialArgs)
: Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs) {}
@@ -3782,19 +3786,19 @@ public:
static SizeOfPackExpr *CreateDeserialized(ASTContext &Context,
unsigned NumPartialArgs);
- /// \brief Determine the location of the 'sizeof' keyword.
+ /// Determine the location of the 'sizeof' keyword.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
- /// \brief Determine the location of the parameter pack.
+ /// Determine the location of the parameter pack.
SourceLocation getPackLoc() const { return PackLoc; }
- /// \brief Determine the location of the right parenthesis.
+ /// Determine the location of the right parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; }
- /// \brief Retrieve the parameter pack.
+ /// Retrieve the parameter pack.
NamedDecl *getPack() const { return Pack; }
- /// \brief Retrieve the length of the parameter pack.
+ /// Retrieve the length of the parameter pack.
///
/// This routine may only be invoked when the expression is not
/// value-dependent.
@@ -3804,7 +3808,7 @@ public:
return Length;
}
- /// \brief Determine whether this represents a partially-substituted sizeof...
+ /// Determine whether this represents a partially-substituted sizeof...
/// expression, such as is produced for:
///
/// template<typename ...Ts> using X = int[sizeof...(Ts)];
@@ -3813,10 +3817,10 @@ public:
return isValueDependent() && Length;
}
- /// \brief Get
+ /// Get
ArrayRef<TemplateArgument> getPartialArguments() const {
assert(isPartiallySubstituted());
- const TemplateArgument *Args = getTrailingObjects<TemplateArgument>();
+ const auto *Args = getTrailingObjects<TemplateArgument>();
return llvm::makeArrayRef(Args, Args + Length);
}
@@ -3833,19 +3837,19 @@ public:
}
};
-/// \brief Represents a reference to a non-type template parameter
+/// Represents a reference to a non-type template parameter
/// that has been substituted with a template argument.
class SubstNonTypeTemplateParmExpr : public Expr {
friend class ASTReader;
friend class ASTStmtReader;
- /// \brief The replaced parameter.
+ /// The replaced parameter.
NonTypeTemplateParmDecl *Param;
- /// \brief The replacement expression.
+ /// The replacement expression.
Stmt *Replacement;
- /// \brief The location of the non-type template parameter reference.
+ /// The location of the non-type template parameter reference.
SourceLocation NameLoc;
explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
@@ -3879,7 +3883,7 @@ public:
child_range children() { return child_range(&Replacement, &Replacement+1); }
};
-/// \brief Represents a reference to a non-type template parameter pack that
+/// Represents a reference to a non-type template parameter pack that
/// has been substituted with a non-template argument pack.
///
/// When a pack expansion in the source code contains multiple parameter packs
@@ -3895,17 +3899,17 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
friend class ASTReader;
friend class ASTStmtReader;
- /// \brief The non-type template parameter pack itself.
+ /// The non-type template parameter pack itself.
NonTypeTemplateParmDecl *Param;
- /// \brief A pointer to the set of template arguments that this
+ /// A pointer to the set of template arguments that this
/// parameter pack is instantiated with.
const TemplateArgument *Arguments;
- /// \brief The number of template arguments in \c Arguments.
+ /// The number of template arguments in \c Arguments.
unsigned NumArguments;
- /// \brief The location of the non-type template parameter pack reference.
+ /// The location of the non-type template parameter pack reference.
SourceLocation NameLoc;
explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)
@@ -3913,17 +3917,18 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
public:
SubstNonTypeTemplateParmPackExpr(QualType T,
+ ExprValueKind ValueKind,
NonTypeTemplateParmDecl *Param,
SourceLocation NameLoc,
const TemplateArgument &ArgPack);
- /// \brief Retrieve the non-type template parameter pack being substituted.
+ /// Retrieve the non-type template parameter pack being substituted.
NonTypeTemplateParmDecl *getParameterPack() const { return Param; }
- /// \brief Retrieve the location of the parameter pack name.
+ /// Retrieve the location of the parameter pack name.
SourceLocation getParameterPackLocation() const { return NameLoc; }
- /// \brief Retrieve the template argument pack containing the substituted
+ /// Retrieve the template argument pack containing the substituted
/// template arguments.
TemplateArgument getArgumentPack() const;
@@ -3940,7 +3945,7 @@ public:
}
};
-/// \brief Represents a reference to a function parameter pack that has been
+/// Represents a reference to a function parameter pack that has been
/// substituted but not yet expanded.
///
/// When a pack expansion contains multiple parameter packs at different levels,
@@ -3961,13 +3966,13 @@ class FunctionParmPackExpr final
friend class ASTStmtReader;
friend TrailingObjects;
- /// \brief The function parameter pack which was referenced.
+ /// The function parameter pack which was referenced.
ParmVarDecl *ParamPack;
- /// \brief The location of the function parameter pack reference.
+ /// The location of the function parameter pack reference.
SourceLocation NameLoc;
- /// \brief The number of expansions of this pack.
+ /// The number of expansions of this pack.
unsigned NumParameters;
FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack,
@@ -3982,22 +3987,22 @@ public:
static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context,
unsigned NumParams);
- /// \brief Get the parameter pack which this expression refers to.
+ /// Get the parameter pack which this expression refers to.
ParmVarDecl *getParameterPack() const { return ParamPack; }
- /// \brief Get the location of the parameter pack.
+ /// Get the location of the parameter pack.
SourceLocation getParameterPackLocation() const { return NameLoc; }
- /// \brief Iterators over the parameters which the parameter pack expanded
+ /// Iterators over the parameters which the parameter pack expanded
/// into.
using iterator = ParmVarDecl * const *;
iterator begin() const { return getTrailingObjects<ParmVarDecl *>(); }
iterator end() const { return begin() + NumParameters; }
- /// \brief Get the number of parameters in this parameter pack.
+ /// Get the number of parameters in this parameter pack.
unsigned getNumExpansions() const { return NumParameters; }
- /// \brief Get an expansion of the parameter pack by index.
+ /// Get an expansion of the parameter pack by index.
ParmVarDecl *getExpansion(unsigned I) const { return begin()[I]; }
SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
@@ -4012,7 +4017,7 @@ public:
}
};
-/// \brief Represents a prvalue temporary that is written into memory so that
+/// Represents a prvalue temporary that is written into memory so that
/// a reference can bind to it.
///
/// Prvalue expressions are materialized when they need to have an address
@@ -4038,11 +4043,11 @@ private:
friend class ASTStmtWriter;
struct ExtraState {
- /// \brief The temporary-generating expression whose value will be
+ /// The temporary-generating expression whose value will be
/// materialized.
Stmt *Temporary;
- /// \brief The declaration which lifetime-extended this reference, if any.
+ /// The declaration which lifetime-extended this reference, if any.
/// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
const ValueDecl *ExtendingDecl;
@@ -4071,11 +4076,11 @@ public:
: State.get<ExtraState *>()->Temporary;
}
- /// \brief Retrieve the temporary-generating subexpression whose value will
+ /// Retrieve the temporary-generating subexpression whose value will
/// be materialized into a glvalue.
Expr *GetTemporaryExpr() const { return static_cast<Expr *>(getTemporary()); }
- /// \brief Retrieve the storage duration for the materialized temporary.
+ /// Retrieve the storage duration for the materialized temporary.
StorageDuration getStorageDuration() const {
const ValueDecl *ExtendingDecl = getExtendingDecl();
if (!ExtendingDecl)
@@ -4093,7 +4098,7 @@ public:
return cast<VarDecl>(ExtendingDecl)->getStorageDuration();
}
- /// \brief Get the declaration which triggered the lifetime-extension of this
+ /// Get the declaration which triggered the lifetime-extension of this
/// temporary, if any.
const ValueDecl *getExtendingDecl() const {
return State.is<Stmt *>() ? nullptr
@@ -4106,7 +4111,7 @@ public:
return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber;
}
- /// \brief Determine whether this materialized temporary is bound to an
+ /// Determine whether this materialized temporary is bound to an
/// lvalue reference; otherwise, it's bound to an rvalue reference.
bool isBoundToLvalueReference() const {
return getValueKind() == VK_LValue;
@@ -4134,7 +4139,7 @@ public:
}
};
-/// \brief Represents a folding of a pack over an operator.
+/// Represents a folding of a pack over an operator.
///
/// This expression is always dependent and represents a pack expansion of the
/// forms:
@@ -4203,7 +4208,7 @@ public:
child_range children() { return child_range(SubExprs, SubExprs + 2); }
};
-/// \brief Represents an expression that might suspend coroutine execution;
+/// Represents an expression that might suspend coroutine execution;
/// either a co_await or co_yield expression.
///
/// Evaluation of this expression first evaluates its 'ready' expression. If
@@ -4267,7 +4272,7 @@ public:
return static_cast<Expr*>(SubExprs[SubExpr::Common]);
}
- /// \brief getOpaqueValue - Return the opaque value placeholder.
+ /// getOpaqueValue - Return the opaque value placeholder.
OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
Expr *getReadyExpr() const {
@@ -4300,7 +4305,7 @@ public:
}
};
-/// \brief Represents a 'co_await' expression.
+/// Represents a 'co_await' expression.
class CoawaitExpr : public CoroutineSuspendExpr {
friend class ASTStmtReader;
@@ -4335,7 +4340,7 @@ public:
}
};
-/// \brief Represents a 'co_await' expression while the type of the promise
+/// Represents a 'co_await' expression while the type of the promise
/// is dependent.
class DependentCoawaitExpr : public Expr {
friend class ASTStmtReader;
@@ -4383,7 +4388,7 @@ public:
}
};
-/// \brief Represents a 'co_yield' expression.
+/// Represents a 'co_yield' expression.
class CoyieldExpr : public CoroutineSuspendExpr {
friend class ASTStmtReader;
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index ab2df8a34819e..5dac0e037da11 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -25,7 +25,6 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
@@ -36,6 +35,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
+#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/type_traits.h"
#include <cassert>
#include <cstddef>
@@ -198,10 +198,10 @@ public:
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- /// \brief Retrieve elements of array of literals.
+ /// Retrieve elements of array of literals.
Expr **getElements() { return getTrailingObjects<Expr *>(); }
- /// \brief Retrieve elements of array of literals.
+ /// Retrieve elements of array of literals.
const Expr * const *getElements() const {
return getTrailingObjects<Expr *>();
}
@@ -212,11 +212,11 @@ public:
/// getElement - Return the Element at the specified index.
Expr *getElement(unsigned Index) {
assert((Index < NumElements) && "Arg access out of range!");
- return cast<Expr>(getElements()[Index]);
+ return getElements()[Index];
}
const Expr *getElement(unsigned Index) const {
assert((Index < NumElements) && "Arg access out of range!");
- return cast<Expr>(getElements()[Index]);
+ return getElements()[Index];
}
ObjCMethodDecl *getArrayWithObjectsMethod() const {
@@ -234,23 +234,23 @@ public:
}
};
-/// \brief An element in an Objective-C dictionary literal.
+/// An element in an Objective-C dictionary literal.
///
struct ObjCDictionaryElement {
- /// \brief The key for the dictionary element.
+ /// The key for the dictionary element.
Expr *Key;
- /// \brief The value of the dictionary element.
+ /// The value of the dictionary element.
Expr *Value;
- /// \brief The location of the ellipsis, if this is a pack expansion.
+ /// The location of the ellipsis, if this is a pack expansion.
SourceLocation EllipsisLoc;
- /// \brief The number of elements this pack expansion will expand to, if
+ /// The number of elements this pack expansion will expand to, if
/// this is a pack expansion and is known.
Optional<unsigned> NumExpansions;
- /// \brief Determines whether this dictionary element is a pack expansion.
+ /// Determines whether this dictionary element is a pack expansion.
bool isPackExpansion() const { return EllipsisLoc.isValid(); }
};
@@ -264,21 +264,21 @@ template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
namespace clang {
-/// \brief Internal struct for storing Key/value pair.
+/// Internal struct for storing Key/value pair.
struct ObjCDictionaryLiteral_KeyValuePair {
Expr *Key;
Expr *Value;
};
-/// \brief Internal struct to describes an element that is a pack
+/// Internal struct to describes an element that is a pack
/// expansion, used if any of the elements in the dictionary literal
/// are pack expansions.
struct ObjCDictionaryLiteral_ExpansionData {
- /// \brief The location of the ellipsis, if this element is a pack
+ /// The location of the ellipsis, if this element is a pack
/// expansion.
SourceLocation EllipsisLoc;
- /// \brief If non-zero, the number of elements that this pack
+ /// If non-zero, the number of elements that this pack
/// expansion will expand to (+1).
unsigned NumExpansionsPlusOne;
};
@@ -290,10 +290,10 @@ class ObjCDictionaryLiteral final
private llvm::TrailingObjects<ObjCDictionaryLiteral,
ObjCDictionaryLiteral_KeyValuePair,
ObjCDictionaryLiteral_ExpansionData> {
- /// \brief The number of elements in this dictionary literal.
+ /// The number of elements in this dictionary literal.
unsigned NumElements : 31;
- /// \brief Determine whether this dictionary literal has any pack expansions.
+ /// Determine whether this dictionary literal has any pack expansions.
///
/// If the dictionary literal has pack expansions, then there will
/// be an array of pack expansion data following the array of
@@ -582,7 +582,7 @@ private:
/// the pointer is an ObjCPropertyDecl and Setter is always null.
llvm::PointerIntPair<NamedDecl *, 1, bool> PropertyOrGetter;
- /// \brief Indicates whether the property reference will result in a message
+ /// Indicates whether the property reference will result in a message
/// to the getter, the setter, or both.
/// This applies to both implicit and explicit property references.
enum MethodRefFlags {
@@ -591,7 +591,7 @@ private:
MethodRef_Setter = 0x2
};
- /// \brief Contains the Setter method pointer and MethodRefFlags bit flags.
+ /// Contains the Setter method pointer and MethodRefFlags bit flags.
llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
// FIXME: Maybe we should store the property identifier here,
@@ -601,7 +601,7 @@ private:
SourceLocation IdLoc;
- /// \brief When the receiver in property access is 'super', this is
+ /// When the receiver in property access is 'super', this is
/// the location of the 'super' keyword. When it's an interface,
/// this is that interface.
SourceLocation ReceiverLoc;
@@ -694,14 +694,14 @@ public:
return getExplicitProperty()->getSetterName();
}
- /// \brief True if the property reference will result in a message to the
+ /// True if the property reference will result in a message to the
/// getter.
/// This applies to both implicit and explicit property references.
bool isMessagingGetter() const {
return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
}
- /// \brief True if the property reference will result in a message to the
+ /// True if the property reference will result in a message to the
/// setter.
/// This applies to both implicit and explicit property references.
bool isMessagingSetter() const {
@@ -874,7 +874,7 @@ private:
friend class ASTStmtReader;
};
-/// \brief An expression that sends a message to the given Objective-C
+/// An expression that sends a message to the given Objective-C
/// object or class.
///
/// The following contains two message send expressions:
@@ -903,47 +903,47 @@ private:
class ObjCMessageExpr final
: public Expr,
private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> {
- /// \brief Stores either the selector that this message is sending
+ /// Stores either the selector that this message is sending
/// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
/// referring to the method that we type-checked against.
uintptr_t SelectorOrMethod = 0;
enum { NumArgsBitWidth = 16 };
- /// \brief The number of arguments in the message send, not
+ /// The number of arguments in the message send, not
/// including the receiver.
unsigned NumArgs : NumArgsBitWidth;
- /// \brief The kind of message send this is, which is one of the
+ /// The kind of message send this is, which is one of the
/// ReceiverKind values.
///
/// We pad this out to a byte to avoid excessive masking and shifting.
unsigned Kind : 8;
- /// \brief Whether we have an actual method prototype in \c
+ /// Whether we have an actual method prototype in \c
/// SelectorOrMethod.
///
/// When non-zero, we have a method declaration; otherwise, we just
/// have a selector.
unsigned HasMethod : 1;
- /// \brief Whether this message send is a "delegate init call",
+ /// Whether this message send is a "delegate init call",
/// i.e. a call of an init method on self from within an init method.
unsigned IsDelegateInitCall : 1;
- /// \brief Whether this message send was implicitly generated by
+ /// Whether this message send was implicitly generated by
/// the implementation rather than explicitly written by the user.
unsigned IsImplicit : 1;
- /// \brief Whether the locations of the selector identifiers are in a
+ /// Whether the locations of the selector identifiers are in a
/// "standard" position, a enum SelectorLocationsKind.
unsigned SelLocsKind : 2;
- /// \brief When the message expression is a send to 'super', this is
+ /// When the message expression is a send to 'super', this is
/// the location of the 'super' keyword.
SourceLocation SuperLoc;
- /// \brief The source locations of the open and close square
+ /// The source locations of the open and close square
/// brackets ('[' and ']', respectively).
SourceLocation LBracLoc, RBracLoc;
@@ -997,10 +997,10 @@ class ObjCMessageExpr final
ArrayRef<SourceLocation> SelLocs,
SelectorLocationsKind SelLocsK);
- /// \brief Retrieve the pointer value of the message receiver.
+ /// Retrieve the pointer value of the message receiver.
void *getReceiverPointer() const { return *getTrailingObjects<void *>(); }
- /// \brief Set the pointer value of the message receiver.
+ /// Set the pointer value of the message receiver.
void setReceiverPointer(void *Value) {
*getTrailingObjects<void *>() = Value;
}
@@ -1013,7 +1013,7 @@ class ObjCMessageExpr final
return getSelLocsKind() != SelLoc_NonStandard;
}
- /// \brief Get a pointer to the stored selector identifiers locations array.
+ /// Get a pointer to the stored selector identifiers locations array.
/// No locations will be stored if HasStandardSelLocs is true.
SourceLocation *getStoredSelLocs() {
return getTrailingObjects<SourceLocation>();
@@ -1022,7 +1022,7 @@ class ObjCMessageExpr final
return getTrailingObjects<SourceLocation>();
}
- /// \brief Get the number of stored selector identifiers locations.
+ /// Get the number of stored selector identifiers locations.
/// No locations will be stored if HasStandardSelLocs is true.
unsigned getNumStoredSelLocs() const {
if (hasStandardSelLocs())
@@ -1045,22 +1045,22 @@ public:
friend class ASTStmtWriter;
friend TrailingObjects;
- /// \brief The kind of receiver this message is sending to.
+ /// The kind of receiver this message is sending to.
enum ReceiverKind {
- /// \brief The receiver is a class.
+ /// The receiver is a class.
Class = 0,
- /// \brief The receiver is an object instance.
+ /// The receiver is an object instance.
Instance,
- /// \brief The receiver is a superclass.
+ /// The receiver is a superclass.
SuperClass,
- /// \brief The receiver is the instance of the superclass object.
+ /// The receiver is the instance of the superclass object.
SuperInstance
};
- /// \brief Create a message send to super.
+ /// Create a message send to super.
///
/// \param Context The ASTContext in which this expression will be created.
///
@@ -1098,7 +1098,7 @@ public:
SourceLocation RBracLoc,
bool isImplicit);
- /// \brief Create a class message send.
+ /// Create a class message send.
///
/// \param Context The ASTContext in which this expression will be created.
///
@@ -1132,7 +1132,7 @@ public:
SourceLocation RBracLoc,
bool isImplicit);
- /// \brief Create an instance message send.
+ /// Create an instance message send.
///
/// \param Context The ASTContext in which this expression will be created.
///
@@ -1166,7 +1166,7 @@ public:
SourceLocation RBracLoc,
bool isImplicit);
- /// \brief Create an empty Objective-C message expression, to be
+ /// Create an empty Objective-C message expression, to be
/// filled in by subsequent calls.
///
/// \param Context The context in which the message send will be created.
@@ -1177,31 +1177,31 @@ public:
unsigned NumArgs,
unsigned NumStoredSelLocs);
- /// \brief Indicates whether the message send was implicitly
+ /// Indicates whether the message send was implicitly
/// generated by the implementation. If false, it was written explicitly
/// in the source code.
bool isImplicit() const { return IsImplicit; }
- /// \brief Determine the kind of receiver that this message is being
+ /// Determine the kind of receiver that this message is being
/// sent to.
ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
- /// \brief Source range of the receiver.
+ /// Source range of the receiver.
SourceRange getReceiverRange() const;
- /// \brief Determine whether this is an instance message to either a
+ /// Determine whether this is an instance message to either a
/// computed object or to super.
bool isInstanceMessage() const {
return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
}
- /// \brief Determine whether this is an class message to either a
+ /// Determine whether this is an class message to either a
/// specified class or to super.
bool isClassMessage() const {
return getReceiverKind() == Class || getReceiverKind() == SuperClass;
}
- /// \brief Returns the object expression (receiver) for an instance message,
+ /// Returns the object expression (receiver) for an instance message,
/// or null for a message that is not an instance message.
Expr *getInstanceReceiver() {
if (getReceiverKind() == Instance)
@@ -1213,14 +1213,14 @@ public:
return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
}
- /// \brief Turn this message send into an instance message that
+ /// Turn this message send into an instance message that
/// computes the receiver object with the given expression.
void setInstanceReceiver(Expr *rec) {
Kind = Instance;
setReceiverPointer(rec);
}
- /// \brief Returns the type of a class message send, or NULL if the
+ /// Returns the type of a class message send, or NULL if the
/// message is not a class message.
QualType getClassReceiver() const {
if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
@@ -1229,7 +1229,7 @@ public:
return {};
}
- /// \brief Returns a type-source information of a class message
+ /// Returns a type-source information of a class message
/// send, or nullptr if the message is not a class message.
TypeSourceInfo *getClassReceiverTypeInfo() const {
if (getReceiverKind() == Class)
@@ -1242,7 +1242,7 @@ public:
setReceiverPointer(TSInfo);
}
- /// \brief Retrieve the location of the 'super' keyword for a class
+ /// Retrieve the location of the 'super' keyword for a class
/// or instance message to 'super', otherwise an invalid source location.
SourceLocation getSuperLoc() const {
if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
@@ -1251,7 +1251,7 @@ public:
return SourceLocation();
}
- /// \brief Retrieve the receiver type to which this message is being directed.
+ /// Retrieve the receiver type to which this message is being directed.
///
/// This routine cross-cuts all of the different kinds of message
/// sends to determine what the underlying (statically known) type
@@ -1262,7 +1262,7 @@ public:
/// \returns The type of the receiver.
QualType getReceiverType() const;
- /// \brief Retrieve the Objective-C interface to which this message
+ /// Retrieve the Objective-C interface to which this message
/// is being directed, if known.
///
/// This routine cross-cuts all of the different kinds of message
@@ -1274,7 +1274,7 @@ public:
/// \returns The Objective-C interface if known, otherwise nullptr.
ObjCInterfaceDecl *getReceiverInterface() const;
- /// \brief Retrieve the type referred to by 'super'.
+ /// Retrieve the type referred to by 'super'.
///
/// The returned type will either be an ObjCInterfaceType (for an
/// class message to super) or an ObjCObjectPointerType that refers
@@ -1323,11 +1323,11 @@ public:
return getSelector().getMethodFamily();
}
- /// \brief Return the number of actual arguments in this message,
+ /// Return the number of actual arguments in this message,
/// not counting the receiver.
unsigned getNumArgs() const { return NumArgs; }
- /// \brief Retrieve the arguments to this message, not including the
+ /// Retrieve the arguments to this message, not including the
/// receiver.
Expr **getArgs() {
return reinterpret_cast<Expr **>(getTrailingObjects<void *>() + 1);
@@ -1455,7 +1455,7 @@ public:
/*ContainsUnexpandedParameterPack=*/false),
Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
- /// \brief Build an empty expression.
+ /// Build an empty expression.
explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {}
void setBase(Expr *E) { Base = E; }
@@ -1563,7 +1563,7 @@ public:
}
};
-/// \brief An Objective-C "bridged" cast expression, which casts between
+/// An Objective-C "bridged" cast expression, which casts between
/// Objective-C pointers and C pointers, transferring ownership in the process.
///
/// \code
@@ -1589,21 +1589,21 @@ public:
CK, Operand, 0, TSInfo),
LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) {}
- /// \brief Construct an empty Objective-C bridged cast.
+ /// Construct an empty Objective-C bridged cast.
explicit ObjCBridgedCastExpr(EmptyShell Shell)
: ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) {}
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Determine which kind of bridge is being performed via this cast.
+ /// Determine which kind of bridge is being performed via this cast.
ObjCBridgeCastKind getBridgeKind() const {
return static_cast<ObjCBridgeCastKind>(Kind);
}
- /// \brief Retrieve the kind of bridge being performed as a string.
+ /// Retrieve the kind of bridge being performed as a string.
StringRef getBridgeKindName() const;
- /// \brief The location of the bridge keyword.
+ /// The location of the bridge keyword.
SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
@@ -1617,7 +1617,7 @@ public:
}
};
-/// \brief A runtime availability query.
+/// A runtime availability query.
///
/// There are 2 ways to spell this node:
/// \code
@@ -1650,7 +1650,7 @@ public:
SourceLocation getLocEnd() const { return RParen; }
SourceRange getSourceRange() const { return {AtLoc, RParen}; }
- /// \brief This may be '*', in which case this should fold to true.
+ /// This may be '*', in which case this should fold to true.
bool hasVersion() const { return !VersionToCheck.empty(); }
VersionTuple getVersion() { return VersionToCheck; }
diff --git a/include/clang/AST/ExprOpenMP.h b/include/clang/AST/ExprOpenMP.h
index a4ef93ba8b14a..2b4b5ec4d0e43 100644
--- a/include/clang/AST/ExprOpenMP.h
+++ b/include/clang/AST/ExprOpenMP.h
@@ -17,7 +17,7 @@
#include "clang/AST/Expr.h"
namespace clang {
-/// \brief OpenMP 4.0 [2.4, Array Sections].
+/// OpenMP 4.0 [2.4, Array Sections].
/// To specify an array section in an OpenMP construct, array subscript
/// expressions are extended with the following syntax:
/// \code
@@ -72,33 +72,33 @@ public:
SubExprs[LENGTH] = Length;
}
- /// \brief Create an empty array section expression.
+ /// Create an empty array section expression.
explicit OMPArraySectionExpr(EmptyShell Shell)
: Expr(OMPArraySectionExprClass, Shell) {}
/// An array section can be written only as Base[LowerBound:Length].
- /// \brief Get base of the array section.
+ /// Get base of the array section.
Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
- /// \brief Set base of the array section.
+ /// Set base of the array section.
void setBase(Expr *E) { SubExprs[BASE] = E; }
- /// \brief Return original type of the base expression for array section.
+ /// Return original type of the base expression for array section.
static QualType getBaseOriginalType(const Expr *Base);
- /// \brief Get lower bound of array section.
+ /// Get lower bound of array section.
Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
const Expr *getLowerBound() const {
return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
}
- /// \brief Set lower bound of the array section.
+ /// Set lower bound of the array section.
void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }
- /// \brief Get length of array section.
+ /// Get length of array section.
Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); }
const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); }
- /// \brief Set length of the array section.
+ /// Set length of the array section.
void setLength(Expr *E) { SubExprs[LENGTH] = E; }
SourceLocation getLocStart() const LLVM_READONLY {
diff --git a/include/clang/AST/ExternalASTMerger.h b/include/clang/AST/ExternalASTMerger.h
index 81492aec6e13e..ae8a761e127e5 100644
--- a/include/clang/AST/ExternalASTMerger.h
+++ b/include/clang/AST/ExternalASTMerger.h
@@ -97,7 +97,7 @@ public:
/// Add a set of ASTContexts as possible origins.
///
/// Usually the set will be initialized in the constructor, but long-lived
- /// ExternalASTMergers may neeed to import from new sources (for example,
+ /// ExternalASTMergers may need to import from new sources (for example,
/// newly-parsed source files).
///
/// Ensures that Importers does not gain duplicate entries as a result.
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index be013c5d6b6a1..82255bb1c44c8 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -19,7 +19,6 @@
#include "clang/AST/DeclBase.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
-#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -54,7 +53,7 @@ class Selector;
class Stmt;
class TagDecl;
-/// \brief Abstract interface for external sources of AST nodes.
+/// Abstract interface for external sources of AST nodes.
///
/// External AST sources provide AST nodes constructed from some
/// external source, such as a precompiled header. External AST
@@ -68,7 +67,7 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
/// whenever we might have added new redeclarations for existing decls.
uint32_t CurrentGeneration = 0;
- /// \brief Whether this AST source also provides information for
+ /// Whether this AST source also provides information for
/// semantic analysis.
bool SemaSource = false;
@@ -76,7 +75,7 @@ public:
ExternalASTSource() = default;
virtual ~ExternalASTSource();
- /// \brief RAII class for safely pairing a StartedDeserializing call
+ /// RAII class for safely pairing a StartedDeserializing call
/// with FinishedDeserializing.
class Deserializing {
ExternalASTSource *Source;
@@ -92,12 +91,12 @@ public:
}
};
- /// \brief Get the current generation of this AST source. This number
+ /// 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
+ /// Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
///
/// This method only needs to be implemented if the AST source ever
@@ -106,7 +105,7 @@ public:
/// The default implementation of this method is a no-op.
virtual Decl *GetExternalDecl(uint32_t ID);
- /// \brief Resolve a selector ID into a selector.
+ /// Resolve a selector ID into a selector.
///
/// This operation only needs to be implemented if the AST source
/// returns non-zero for GetNumKnownSelectors().
@@ -114,13 +113,13 @@ public:
/// The default implementation of this method is a no-op.
virtual Selector GetExternalSelector(uint32_t ID);
- /// \brief Returns the number of selectors known to the external AST
+ /// Returns the number of selectors known to the external AST
/// source.
///
/// The default implementation of this method is a no-op.
virtual uint32_t GetNumExternalSelectors();
- /// \brief Resolve the offset of a statement in the decl stream into
+ /// Resolve the offset of a statement in the decl stream into
/// a statement.
///
/// This operation is meant to be used via a LazyOffsetPtr. It only
@@ -130,22 +129,22 @@ public:
/// The default implementation of this method is a no-op.
virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
- /// \brief Resolve the offset of a set of C++ constructor initializers in
+ /// Resolve the offset of a set of C++ constructor initializers in
/// the decl stream into an array of initializers.
///
/// The default implementation of this method is a no-op.
virtual CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset);
- /// \brief Resolve the offset of a set of C++ base specifiers in the decl
+ /// Resolve the offset of a set of C++ base specifiers in the decl
/// stream into an array of specifiers.
///
/// The default implementation of this method is a no-op.
virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
- /// \brief Update an out-of-date identifier.
+ /// Update an out-of-date identifier.
virtual void updateOutOfDateIdentifier(IdentifierInfo &II) {}
- /// \brief Find all declarations with the given name in the given context,
+ /// Find all declarations with the given name in the given context,
/// and add them to the context by calling SetExternalVisibleDeclsForName
/// or SetNoExternalVisibleDeclsForName.
/// \return \c true if any declarations might have been found, \c false if
@@ -155,15 +154,19 @@ public:
virtual bool
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
- /// \brief Ensures that the table of all visible declarations inside this
+ /// Ensures that the table of all visible declarations inside this
/// context is up to date.
///
/// The default implementation of this function is a no-op.
virtual void completeVisibleDeclsMap(const DeclContext *DC);
- /// \brief Retrieve the module that corresponds to the given module ID.
+ /// Retrieve the module that corresponds to the given module ID.
virtual Module *getModule(unsigned ID) { return nullptr; }
+ /// Determine whether D comes from a PCH which was built with a corresponding
+ /// object file.
+ virtual bool DeclIsFromPCHWithObjectFile(const Decl *D) { return false; }
+
/// Abstracts clang modules and precompiled header files and holds
/// everything needed to generate debug info for an imported module
/// or PCH.
@@ -196,7 +199,7 @@ public:
virtual ExtKind hasExternalDefinitions(const Decl *D);
- /// \brief Finds all declarations lexically contained within the given
+ /// Finds all declarations lexically contained within the given
/// DeclContext, after applying an optional filter predicate.
///
/// \param IsKindWeWant a predicate function that returns true if the passed
@@ -208,31 +211,31 @@ public:
llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
SmallVectorImpl<Decl *> &Result);
- /// \brief Finds all declarations lexically contained within the given
+ /// Finds all declarations lexically contained within the given
/// DeclContext.
void FindExternalLexicalDecls(const DeclContext *DC,
SmallVectorImpl<Decl *> &Result) {
FindExternalLexicalDecls(DC, [](Decl::Kind) { return true; }, Result);
}
- /// \brief Get the decls that are contained in a file in the Offset/Length
+ /// 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);
- /// \brief Gives the external AST source an opportunity to complete
+ /// 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
+ /// Gives the external AST source an opportunity to complete
/// an incomplete type.
virtual void CompleteType(TagDecl *Tag);
- /// \brief Gives the external AST source an opportunity to complete an
+ /// 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
@@ -240,35 +243,35 @@ public:
/// \c ObjCInterfaceDecl::setExternallyCompleted().
virtual void CompleteType(ObjCInterfaceDecl *Class);
- /// \brief Loads comment ranges.
+ /// Loads comment ranges.
virtual void ReadComments();
- /// \brief Notify ExternalASTSource that we started deserialization of
+ /// 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();
- /// \brief Notify ExternalASTSource that we finished the deserialization of
+ /// 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();
- /// \brief Function that will be invoked when we begin parsing a new
+ /// 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);
- /// \brief Print any statistics that have been gathered regarding
+ /// Print any statistics that have been gathered regarding
/// the external AST source.
///
/// The default implementation of this method is a no-op.
virtual void PrintStats();
- /// \brief Perform layout on the given record.
+ /// Perform layout on the given record.
///
/// This routine allows the external AST source to provide an specific
/// layout for a record, overriding the layout that would normally be
@@ -333,11 +336,11 @@ protected:
SetNoExternalVisibleDeclsForName(const DeclContext *DC,
DeclarationName Name);
- /// \brief Increment the current generation.
+ /// Increment the current generation.
uint32_t incrementGeneration(ASTContext &C);
};
-/// \brief A lazy pointer to an AST node (of base type T) that resides
+/// A lazy pointer to an AST node (of base type T) that resides
/// within an external AST source.
///
/// The AST node is identified within the external AST source by a
@@ -345,7 +348,7 @@ protected:
/// external AST source itself.
template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
struct LazyOffsetPtr {
- /// \brief Either a pointer to an AST node or the offset within the
+ /// Either a pointer to an AST node or the offset within the
/// external AST source where the AST node can be found.
///
/// If the low bit is clear, a pointer to the AST node. If the low
@@ -377,20 +380,20 @@ public:
return *this;
}
- /// \brief Whether this pointer is non-NULL.
+ /// Whether this pointer is non-NULL.
///
/// This operation does not require the AST node to be deserialized.
explicit operator bool() const { return Ptr != 0; }
- /// \brief Whether this pointer is non-NULL.
+ /// Whether this pointer is non-NULL.
///
/// This operation does not require the AST node to be deserialized.
bool isValid() const { return Ptr != 0; }
- /// \brief Whether this pointer is currently stored as an offset.
+ /// Whether this pointer is currently stored as an offset.
bool isOffset() const { return Ptr & 0x01; }
- /// \brief Retrieve the pointer to the AST node that this lazy pointer
+ /// Retrieve the pointer to the AST node that this lazy pointer points to.
///
/// \param Source the external AST source.
///
@@ -405,7 +408,7 @@ public:
}
};
-/// \brief A lazy value (of type T) that is within an AST node of type Owner,
+/// 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)>
@@ -447,7 +450,7 @@ public:
/// Set the value of this pointer, in the current generation.
void set(T NewValue) {
- if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
+ if (auto *LazyVal = Value.template dyn_cast<LazyData *>()) {
LazyVal->LastValue = NewValue;
return;
}
@@ -459,7 +462,7 @@ public:
/// Get the value of this pointer, updating its owner if necessary.
T get(Owner O) {
- if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
+ if (auto *LazyVal = Value.template dyn_cast<LazyData *>()) {
if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) {
LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration();
(LazyVal->ExternalSource->*Update)(O);
@@ -471,7 +474,7 @@ public:
/// Get the most recently computed value of this pointer without updating it.
T getNotUpdated() const {
- if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>())
+ if (auto *LazyVal = Value.template dyn_cast<LazyData *>())
return LazyVal->LastValue;
return Value.template get<T>();
}
@@ -506,7 +509,7 @@ struct PointerLikeTypeTraits<
namespace clang {
-/// \brief Represents a lazily-loaded vector of data.
+/// Represents a lazily-loaded vector of data.
///
/// The lazily-loaded vector of data contains data that is partially loaded
/// from an external source and partially added by local translation. The
@@ -590,20 +593,20 @@ public:
}
};
-/// \brief A lazy pointer to a statement.
+/// A lazy pointer to a statement.
using LazyDeclStmtPtr =
LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>;
-/// \brief A lazy pointer to a declaration.
+/// A lazy pointer to a declaration.
using LazyDeclPtr =
LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>;
-/// \brief A lazy pointer to a set of CXXCtorInitializers.
+/// A lazy pointer to a set of CXXCtorInitializers.
using LazyCXXCtorInitializersPtr =
LazyOffsetPtr<CXXCtorInitializer *, uint64_t,
&ExternalASTSource::GetExternalCXXCtorInitializers>;
-/// \brief A lazy pointer to a set of CXXBaseSpecifiers.
+/// A lazy pointer to a set of CXXBaseSpecifiers.
using LazyCXXBaseSpecifiersPtr =
LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
&ExternalASTSource::GetExternalCXXBaseSpecifiers>;
diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h
index 6517d656878ee..bcc5352c1c9dd 100644
--- a/include/clang/AST/LambdaCapture.h
+++ b/include/clang/AST/LambdaCapture.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the LambdaCapture class.
+/// Defines the LambdaCapture class.
///
//===----------------------------------------------------------------------===//
@@ -21,21 +21,21 @@
namespace clang {
-/// \brief Describes the capture of a variable or of \c this, or of a
+/// 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
+ /// 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
+ /// 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 Flag used by the Capture class to distinguish between a capture
+ /// Flag used by the Capture class to distinguish between a capture
/// of '*this' and a capture of a VLA type.
Capture_This = 0x04
};
@@ -56,7 +56,7 @@ class LambdaCapture {
friend class ASTStmtWriter;
public:
- /// \brief Create a new capture of a variable or of \c this.
+ /// Create a new capture of a variable or of \c this.
///
/// \param Loc The source location associated with this capture.
///
@@ -75,29 +75,29 @@ public:
VarDecl *Var = nullptr,
SourceLocation EllipsisLoc = SourceLocation());
- /// \brief Determine the kind of capture.
+ /// Determine the kind of capture.
LambdaCaptureKind getCaptureKind() const;
- /// \brief Determine whether this capture handles the C++ \c this
+ /// Determine whether this capture handles the C++ \c this
/// pointer.
bool capturesThis() const {
return DeclAndBits.getPointer() == nullptr &&
(DeclAndBits.getInt() & Capture_This);
}
- /// \brief Determine whether this capture handles a variable.
+ /// Determine whether this capture handles a variable.
bool capturesVariable() const {
return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
}
- /// \brief Determine whether this captures a variable length array bound
+ /// Determine whether this captures a variable length array bound
/// expression.
bool capturesVLAType() const {
return DeclAndBits.getPointer() == nullptr &&
!(DeclAndBits.getInt() & Capture_This);
}
- /// \brief Retrieve the declaration of the local variable being
+ /// Retrieve the declaration of the local variable being
/// captured.
///
/// This operation is only valid if this capture is a variable capture
@@ -107,17 +107,17 @@ public:
return static_cast<VarDecl *>(DeclAndBits.getPointer());
}
- /// \brief Determine whether this was an implicit capture (not
+ /// 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
+ /// 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.
+ /// 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
@@ -125,11 +125,11 @@ public:
/// used.
SourceLocation getLocation() const { return Loc; }
- /// \brief Determine whether this capture is a pack expansion,
+ /// 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
+ /// 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");
diff --git a/include/clang/AST/LocInfoType.h b/include/clang/AST/LocInfoType.h
index 7e573bd7bac44..802d9134ebde8 100644
--- a/include/clang/AST/LocInfoType.h
+++ b/include/clang/AST/LocInfoType.h
@@ -20,7 +20,7 @@ namespace clang {
class TypeSourceInfo;
-/// \brief Holds a QualType and a TypeSourceInfo* that came out of a declarator
+/// Holds a QualType and a TypeSourceInfo* that came out of a declarator
/// parsing.
///
/// LocInfoType is a "transient" type, only needed for passing to/from Parser
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index 7a45d88c23c8f..401574b265b0e 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -30,6 +30,7 @@ namespace clang {
class CXXDestructorDecl;
class CXXMethodDecl;
class FunctionDecl;
+ struct MethodVFTableLocation;
class NamedDecl;
class ObjCMethodDecl;
class StringLiteral;
@@ -182,14 +183,14 @@ public:
explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
: MangleContext(C, D, MK_Microsoft) {}
- /// \brief Mangle vftable symbols. Only a subset of the bases along the path
+ /// Mangle vftable symbols. Only a subset of the bases along the path
/// to the vftable are included in the name. It's up to the caller to pick
/// them correctly.
virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) = 0;
- /// \brief Mangle vbtable symbols. Only a subset of the bases along the path
+ /// Mangle vbtable symbols. Only a subset of the bases along the path
/// to the vbtable are included in the name. It's up to the caller to pick
/// them correctly.
virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
@@ -201,7 +202,8 @@ public:
raw_ostream &Out) = 0;
virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
- raw_ostream &) = 0;
+ const MethodVFTableLocation &ML,
+ raw_ostream &Out) = 0;
virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
const CXXRecordDecl *DstRD,
diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h
index 869221dbf31b6..ff2148e3516db 100644
--- a/include/clang/AST/MangleNumberingContext.h
+++ b/include/clang/AST/MangleNumberingContext.h
@@ -27,29 +27,29 @@ class TagDecl;
class Type;
class VarDecl;
-/// \brief Keeps track of the mangled names of lambda expressions and block
+/// Keeps track of the mangled names of lambda expressions and block
/// literals within a particular context.
class MangleNumberingContext {
public:
virtual ~MangleNumberingContext() {}
- /// \brief Retrieve the mangling number of a new lambda expression with the
+ /// Retrieve the mangling number of a new lambda expression with the
/// given call operator within this context.
virtual unsigned getManglingNumber(const CXXMethodDecl *CallOperator) = 0;
- /// \brief Retrieve the mangling number of a new block literal within this
+ /// Retrieve the mangling number of a new block literal within this
/// context.
virtual unsigned getManglingNumber(const BlockDecl *BD) = 0;
/// Static locals are numbered by source order.
virtual unsigned getStaticLocalNumber(const VarDecl *VD) = 0;
- /// \brief Retrieve the mangling number of a static local variable within
+ /// Retrieve the mangling number of a static local variable within
/// this context.
virtual unsigned getManglingNumber(const VarDecl *VD,
unsigned MSLocalManglingNumber) = 0;
- /// \brief Retrieve the mangling number of a static local variable within
+ /// Retrieve the mangling number of a static local variable within
/// this context.
virtual unsigned getManglingNumber(const TagDecl *TD,
unsigned MSLocalManglingNumber) = 0;
diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h
index 3757116e7c70e..ee07745b1242f 100644
--- a/include/clang/AST/NSAPI.h
+++ b/include/clang/AST/NSAPI.h
@@ -20,7 +20,7 @@ namespace clang {
class QualType;
class Expr;
-// \brief Provides info and caches identifiers/selectors for NSFoundation API.
+// Provides info and caches identifiers/selectors for NSFoundation API.
class NSAPI {
public:
explicit NSAPI(ASTContext &Ctx);
@@ -53,25 +53,25 @@ public:
IdentifierInfo *getNSClassId(NSClassIdKindKind K) const;
- /// \brief The Objective-C NSString selectors.
+ /// The Objective-C NSString selectors.
Selector getNSStringSelector(NSStringMethodKind MK) const;
- /// \brief Return NSStringMethodKind if \param Sel is such a selector.
+ /// Return NSStringMethodKind if \param Sel is such a selector.
Optional<NSStringMethodKind> getNSStringMethodKind(Selector Sel) const;
- /// \brief Returns true if the expression \param E is a reference of
+ /// Returns true if the expression \param E is a reference of
/// "NSUTF8StringEncoding" enum constant.
bool isNSUTF8StringEncodingConstant(const Expr *E) const {
return isObjCEnumerator(E, "NSUTF8StringEncoding", NSUTF8StringEncodingId);
}
- /// \brief Returns true if the expression \param E is a reference of
+ /// Returns true if the expression \param E is a reference of
/// "NSASCIIStringEncoding" enum constant.
bool isNSASCIIStringEncodingConstant(const Expr *E) const {
return isObjCEnumerator(E, "NSASCIIStringEncoding",NSASCIIStringEncodingId);
}
- /// \brief Enumerates the NSArray/NSMutableArray methods used to generate
+ /// Enumerates the NSArray/NSMutableArray methods used to generate
/// literals and to apply some checks.
enum NSArrayMethodKind {
NSArr_array,
@@ -89,13 +89,13 @@ public:
};
static const unsigned NumNSArrayMethods = 12;
- /// \brief The Objective-C NSArray selectors.
+ /// The Objective-C NSArray selectors.
Selector getNSArraySelector(NSArrayMethodKind MK) const;
- /// \brief Return NSArrayMethodKind if \p Sel is such a selector.
+ /// Return NSArrayMethodKind if \p Sel is such a selector.
Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
- /// \brief Enumerates the NSDictionary/NSMutableDictionary methods used
+ /// Enumerates the NSDictionary/NSMutableDictionary methods used
/// to generate literals and to apply some checks.
enum NSDictionaryMethodKind {
NSDict_dictionary,
@@ -114,13 +114,13 @@ public:
};
static const unsigned NumNSDictionaryMethods = 13;
- /// \brief The Objective-C NSDictionary selectors.
+ /// The Objective-C NSDictionary selectors.
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
- /// \brief Return NSDictionaryMethodKind if \p Sel is such a selector.
+ /// Return NSDictionaryMethodKind if \p Sel is such a selector.
Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
- /// \brief Enumerates the NSMutableSet/NSOrderedSet methods used
+ /// Enumerates the NSMutableSet/NSOrderedSet methods used
/// to apply some checks.
enum NSSetMethodKind {
NSMutableSet_addObject,
@@ -131,42 +131,42 @@ public:
};
static const unsigned NumNSSetMethods = 5;
- /// \brief The Objective-C NSSet selectors.
+ /// The Objective-C NSSet selectors.
Selector getNSSetSelector(NSSetMethodKind MK) const;
- /// \brief Return NSSetMethodKind if \p Sel is such a selector.
+ /// Return NSSetMethodKind if \p Sel is such a selector.
Optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel);
- /// \brief Returns selector for "objectForKeyedSubscript:".
+ /// Returns selector for "objectForKeyedSubscript:".
Selector getObjectForKeyedSubscriptSelector() const {
return getOrInitSelector(StringRef("objectForKeyedSubscript"),
objectForKeyedSubscriptSel);
}
- /// \brief Returns selector for "objectAtIndexedSubscript:".
+ /// Returns selector for "objectAtIndexedSubscript:".
Selector getObjectAtIndexedSubscriptSelector() const {
return getOrInitSelector(StringRef("objectAtIndexedSubscript"),
objectAtIndexedSubscriptSel);
}
- /// \brief Returns selector for "setObject:forKeyedSubscript".
+ /// Returns selector for "setObject:forKeyedSubscript".
Selector getSetObjectForKeyedSubscriptSelector() const {
StringRef Ids[] = { "setObject", "forKeyedSubscript" };
return getOrInitSelector(Ids, setObjectForKeyedSubscriptSel);
}
- /// \brief Returns selector for "setObject:atIndexedSubscript".
+ /// Returns selector for "setObject:atIndexedSubscript".
Selector getSetObjectAtIndexedSubscriptSelector() const {
StringRef Ids[] = { "setObject", "atIndexedSubscript" };
return getOrInitSelector(Ids, setObjectAtIndexedSubscriptSel);
}
- /// \brief Returns selector for "isEqual:".
+ /// Returns selector for "isEqual:".
Selector getIsEqualSelector() const {
return getOrInitSelector(StringRef("isEqual"), isEqualSel);
}
- /// \brief Enumerates the NSNumber methods used to generate literals.
+ /// Enumerates the NSNumber methods used to generate literals.
enum NSNumberLiteralMethodKind {
NSNumberWithChar,
NSNumberWithUnsignedChar,
@@ -186,7 +186,7 @@ public:
};
static const unsigned NumNSNumberLiteralMethods = 15;
- /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
+ /// The Objective-C NSNumber selectors used to create NSNumber literals.
/// \param Instance if true it will return the selector for the init* method
/// otherwise it will return the selector for the number* method.
Selector getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
@@ -198,29 +198,29 @@ public:
Sel == getNSNumberLiteralSelector(MK, true);
}
- /// \brief Return NSNumberLiteralMethodKind if \p Sel is such a selector.
+ /// Return NSNumberLiteralMethodKind if \p Sel is such a selector.
Optional<NSNumberLiteralMethodKind>
getNSNumberLiteralMethodKind(Selector Sel) const;
- /// \brief Determine the appropriate NSNumber factory method kind for a
+ /// Determine the appropriate NSNumber factory method kind for a
/// literal of the given type.
Optional<NSNumberLiteralMethodKind>
getNSNumberFactoryMethodKind(QualType T) const;
- /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
+ /// Returns true if \param T is a typedef of "BOOL" in objective-c.
bool isObjCBOOLType(QualType T) const;
- /// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
+ /// Returns true if \param T is a typedef of "NSInteger" in objective-c.
bool isObjCNSIntegerType(QualType T) const;
- /// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
+ /// Returns true if \param T is a typedef of "NSUInteger" in objective-c.
bool isObjCNSUIntegerType(QualType T) const;
- /// \brief Returns one of NSIntegral typedef names if \param T is a typedef
+ /// Returns one of NSIntegral typedef names if \param T is a typedef
/// of that name in objective-c.
StringRef GetNSIntegralKind(QualType T) const;
- /// \brief Returns \c true if \p Id is currently defined as a macro.
+ /// Returns \c true if \p Id is currently defined as a macro.
bool isMacroDefined(StringRef Id) const;
- /// \brief Returns \c true if \p InterfaceDecl is subclass of \p NSClassKind
+ /// Returns \c true if \p InterfaceDecl is subclass of \p NSClassKind
bool isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
NSClassIdKindKind NSClassKind) const;
@@ -236,16 +236,16 @@ private:
mutable Selector NSStringSelectors[NumNSStringMethods];
- /// \brief The selectors for Objective-C NSArray methods.
+ /// The selectors for Objective-C NSArray methods.
mutable Selector NSArraySelectors[NumNSArrayMethods];
- /// \brief The selectors for Objective-C NSDictionary methods.
+ /// The selectors for Objective-C NSDictionary methods.
mutable Selector NSDictionarySelectors[NumNSDictionaryMethods];
- /// \brief The selectors for Objective-C NSSet methods.
+ /// The selectors for Objective-C NSSet methods.
mutable Selector NSSetSelectors[NumNSSetMethods];
- /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
+ /// The Objective-C NSNumber selectors used to create NSNumber literals.
mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];
mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index e2cb45c36de6b..2255d5114350e 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -36,7 +36,7 @@ struct PrintingPolicy;
class Type;
class TypeLoc;
-/// \brief Represents a C++ nested name specifier, such as
+/// Represents a C++ nested name specifier, such as
/// "\::std::vector<int>::".
///
/// C++ nested name specifiers are the prefixes to qualified
@@ -47,7 +47,7 @@ class TypeLoc;
/// The last two specifiers can only appear at the start of a
/// nested-namespace-specifier.
class NestedNameSpecifier : public llvm::FoldingSetNode {
- /// \brief Enumeration describing
+ /// Enumeration describing
enum StoredSpecifierKind {
StoredIdentifier = 0,
StoredDecl = 1,
@@ -55,7 +55,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
StoredTypeSpecWithTemplate = 3
};
- /// \brief The nested name specifier that precedes this nested name
+ /// The nested name specifier that precedes this nested name
/// specifier.
///
/// The pointer is the nested-name-specifier that precedes this
@@ -63,7 +63,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
/// SpecifierKind.
llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
- /// \brief The last component in the nested name specifier, which
+ /// The last component in the nested name specifier, which
/// can be an identifier, a declaration, or a type.
///
/// When the pointer is NULL, this specifier represents the global
@@ -73,42 +73,42 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
void* Specifier = nullptr;
public:
- /// \brief The kind of specifier that completes this nested name
+ /// The kind of specifier that completes this nested name
/// specifier.
enum SpecifierKind {
- /// \brief An identifier, stored as an IdentifierInfo*.
+ /// An identifier, stored as an IdentifierInfo*.
Identifier,
- /// \brief A namespace, stored as a NamespaceDecl*.
+ /// A namespace, stored as a NamespaceDecl*.
Namespace,
- /// \brief A namespace alias, stored as a NamespaceAliasDecl*.
+ /// A namespace alias, stored as a NamespaceAliasDecl*.
NamespaceAlias,
- /// \brief A type, stored as a Type*.
+ /// A type, stored as a Type*.
TypeSpec,
- /// \brief A type that was preceded by the 'template' keyword,
+ /// A type that was preceded by the 'template' keyword,
/// stored as a Type*.
TypeSpecWithTemplate,
- /// \brief The global specifier '::'. There is no stored value.
+ /// The global specifier '::'. There is no stored value.
Global,
- /// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
+ /// Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
/// the class it appeared in.
Super
};
private:
- /// \brief Builds the global specifier.
+ /// Builds the global specifier.
NestedNameSpecifier() : Prefix(nullptr, StoredIdentifier) {}
- /// \brief Copy constructor used internally to clone nested name
+ /// Copy constructor used internally to clone nested name
/// specifiers.
NestedNameSpecifier(const NestedNameSpecifier &Other) = default;
- /// \brief Either find or insert the given nested name specifier
+ /// Either find or insert the given nested name specifier
/// mockup in the given context.
static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
const NestedNameSpecifier &Mockup);
@@ -116,7 +116,7 @@ private:
public:
NestedNameSpecifier &operator=(const NestedNameSpecifier &) = delete;
- /// \brief Builds a specifier combining a prefix and an identifier.
+ /// Builds a specifier combining a prefix and an identifier.
///
/// The prefix must be dependent, since nested name specifiers
/// referencing an identifier are only permitted when the identifier
@@ -125,22 +125,22 @@ public:
NestedNameSpecifier *Prefix,
IdentifierInfo *II);
- /// \brief Builds a nested name specifier that names a namespace.
+ /// Builds a nested name specifier that names a namespace.
static NestedNameSpecifier *Create(const ASTContext &Context,
NestedNameSpecifier *Prefix,
const NamespaceDecl *NS);
- /// \brief Builds a nested name specifier that names a namespace alias.
+ /// Builds a nested name specifier that names a namespace alias.
static NestedNameSpecifier *Create(const ASTContext &Context,
NestedNameSpecifier *Prefix,
NamespaceAliasDecl *Alias);
- /// \brief Builds a nested name specifier that names a type.
+ /// Builds a nested name specifier that names a type.
static NestedNameSpecifier *Create(const ASTContext &Context,
NestedNameSpecifier *Prefix,
bool Template, const Type *T);
- /// \brief Builds a specifier that consists of just an identifier.
+ /// Builds a specifier that consists of just an identifier.
///
/// The nested-name-specifier is assumed to be dependent, but has no
/// prefix because the prefix is implied by something outside of the
@@ -149,16 +149,16 @@ public:
static NestedNameSpecifier *Create(const ASTContext &Context,
IdentifierInfo *II);
- /// \brief Returns the nested name specifier representing the global
+ /// Returns the nested name specifier representing the global
/// scope.
static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
- /// \brief Returns the nested name specifier representing the __super scope
+ /// Returns the nested name specifier representing the __super scope
/// for the given CXXRecordDecl.
static NestedNameSpecifier *SuperSpecifier(const ASTContext &Context,
CXXRecordDecl *RD);
- /// \brief Return the prefix of this nested name specifier.
+ /// Return the prefix of this nested name specifier.
///
/// The prefix contains all of the parts of the nested name
/// specifier that preced this current specifier. For example, for a
@@ -167,10 +167,10 @@ public:
/// "foo::".
NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
- /// \brief Determine what kind of nested name specifier is stored.
+ /// Determine what kind of nested name specifier is stored.
SpecifierKind getKind() const;
- /// \brief Retrieve the identifier stored in this nested name
+ /// Retrieve the identifier stored in this nested name
/// specifier.
IdentifierInfo *getAsIdentifier() const {
if (Prefix.getInt() == StoredIdentifier)
@@ -179,19 +179,19 @@ public:
return nullptr;
}
- /// \brief Retrieve the namespace stored in this nested name
+ /// Retrieve the namespace stored in this nested name
/// specifier.
NamespaceDecl *getAsNamespace() const;
- /// \brief Retrieve the namespace alias stored in this nested name
+ /// Retrieve the namespace alias stored in this nested name
/// specifier.
NamespaceAliasDecl *getAsNamespaceAlias() const;
- /// \brief Retrieve the record declaration stored in this nested name
+ /// Retrieve the record declaration stored in this nested name
/// specifier.
CXXRecordDecl *getAsRecordDecl() const;
- /// \brief Retrieve the type stored in this nested name specifier.
+ /// Retrieve the type stored in this nested name specifier.
const Type *getAsType() const {
if (Prefix.getInt() == StoredTypeSpec ||
Prefix.getInt() == StoredTypeSpecWithTemplate)
@@ -200,19 +200,19 @@ public:
return nullptr;
}
- /// \brief Whether this nested name specifier refers to a dependent
+ /// Whether this nested name specifier refers to a dependent
/// type or not.
bool isDependent() const;
- /// \brief Whether this nested name specifier involves a template
+ /// Whether this nested name specifier involves a template
/// parameter.
bool isInstantiationDependent() const;
- /// \brief Whether this nested-name-specifier contains an unexpanded
+ /// Whether this nested-name-specifier contains an unexpanded
/// parameter pack (for C++11 variadic templates).
bool containsUnexpandedParameterPack() const;
- /// \brief Print this nested name specifier to the given output
+ /// Print this nested name specifier to the given output
/// stream.
void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
@@ -221,53 +221,53 @@ public:
ID.AddPointer(Specifier);
}
- /// \brief Dump the nested name specifier to standard output to aid
+ /// Dump the nested name specifier to standard output to aid
/// in debugging.
void dump(const LangOptions &LO) const;
void dump() const;
};
-/// \brief A C++ nested-name-specifier augmented with source location
+/// A C++ nested-name-specifier augmented with source location
/// information.
class NestedNameSpecifierLoc {
NestedNameSpecifier *Qualifier = nullptr;
void *Data = nullptr;
- /// \brief Determines the data length for the last component in the
+ /// Determines the data length for the last component in the
/// given nested-name-specifier.
static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);
- /// \brief Determines the data length for the entire
+ /// Determines the data length for the entire
/// nested-name-specifier.
static unsigned getDataLength(NestedNameSpecifier *Qualifier);
public:
- /// \brief Construct an empty nested-name-specifier.
+ /// Construct an empty nested-name-specifier.
NestedNameSpecifierLoc() = default;
- /// \brief Construct a nested-name-specifier with source location information
+ /// Construct a nested-name-specifier with source location information
/// from
NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
: Qualifier(Qualifier), Data(Data) {}
- /// \brief Evalutes true when this nested-name-specifier location is
+ /// Evaluates true when this nested-name-specifier location is
/// non-empty.
explicit operator bool() const { return Qualifier; }
- /// \brief Evalutes true when this nested-name-specifier location is
+ /// Evaluates true when this nested-name-specifier location is
/// empty.
bool hasQualifier() const { return Qualifier; }
- /// \brief Retrieve the nested-name-specifier to which this instance
+ /// Retrieve the nested-name-specifier to which this instance
/// refers.
NestedNameSpecifier *getNestedNameSpecifier() const {
return Qualifier;
}
- /// \brief Retrieve the opaque pointer that refers to source-location data.
+ /// Retrieve the opaque pointer that refers to source-location data.
void *getOpaqueData() const { return Data; }
- /// \brief Retrieve the source range covering the entirety of this
+ /// Retrieve the source range covering the entirety of this
/// nested-name-specifier.
///
/// For example, if this instance refers to a nested-name-specifier
@@ -275,7 +275,7 @@ public:
/// from the initial '::' to the last '::'.
SourceRange getSourceRange() const LLVM_READONLY;
- /// \brief Retrieve the source range covering just the last part of
+ /// Retrieve the source range covering just the last part of
/// this nested-name-specifier, not including the prefix.
///
/// For example, if this instance refers to a nested-name-specifier
@@ -283,31 +283,31 @@ public:
/// from "vector" to the last '::'.
SourceRange getLocalSourceRange() const;
- /// \brief Retrieve the location of the beginning of this
+ /// Retrieve the location of the beginning of this
/// nested-name-specifier.
SourceLocation getBeginLoc() const {
return getSourceRange().getBegin();
}
- /// \brief Retrieve the location of the end of this
+ /// Retrieve the location of the end of this
/// nested-name-specifier.
SourceLocation getEndLoc() const {
return getSourceRange().getEnd();
}
- /// \brief Retrieve the location of the beginning of this
+ /// Retrieve the location of the beginning of this
/// component of the nested-name-specifier.
SourceLocation getLocalBeginLoc() const {
return getLocalSourceRange().getBegin();
}
- /// \brief Retrieve the location of the end of this component of the
+ /// Retrieve the location of the end of this component of the
/// nested-name-specifier.
SourceLocation getLocalEndLoc() const {
return getLocalSourceRange().getEnd();
}
- /// \brief Return the prefix of this nested-name-specifier.
+ /// Return the prefix of this nested-name-specifier.
///
/// For example, if this instance refers to a nested-name-specifier
/// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the
@@ -320,11 +320,11 @@ public:
return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
}
- /// \brief For a nested-name-specifier that refers to a type,
+ /// For a nested-name-specifier that refers to a type,
/// retrieve the type with source-location information.
TypeLoc getTypeLoc() const;
- /// \brief Determines the data length for the entire
+ /// Determines the data length for the entire
/// nested-name-specifier.
unsigned getDataLength() const { return getDataLength(Qualifier); }
@@ -339,15 +339,15 @@ public:
}
};
-/// \brief Class that aids in the construction of nested-name-specifiers along
+/// Class that aids in the construction of nested-name-specifiers along
/// with source-location information for all of the components of the
/// nested-name-specifier.
class NestedNameSpecifierLocBuilder {
- /// \brief The current representation of the nested-name-specifier we're
+ /// The current representation of the nested-name-specifier we're
/// building.
NestedNameSpecifier *Representation = nullptr;
- /// \brief Buffer used to store source-location information for the
+ /// Buffer used to store source-location information for the
/// nested-name-specifier.
///
/// Note that we explicitly manage the buffer (rather than using a
@@ -355,11 +355,11 @@ class NestedNameSpecifierLocBuilder {
/// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
char *Buffer = nullptr;
- /// \brief The size of the buffer used to store source-location information
+ /// The size of the buffer used to store source-location information
/// for the nested-name-specifier.
unsigned BufferSize = 0;
- /// \brief The capacity of the buffer used to store source-location
+ /// The capacity of the buffer used to store source-location
/// information for the nested-name-specifier.
unsigned BufferCapacity = 0;
@@ -375,10 +375,10 @@ public:
free(Buffer);
}
- /// \brief Retrieve the representation of the nested-name-specifier.
+ /// Retrieve the representation of the nested-name-specifier.
NestedNameSpecifier *getRepresentation() const { return Representation; }
- /// \brief Extend the current nested-name-specifier by another
+ /// Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'type::'.
///
/// \param Context The AST context in which this nested-name-specifier
@@ -392,7 +392,7 @@ public:
void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
SourceLocation ColonColonLoc);
- /// \brief Extend the current nested-name-specifier by another
+ /// Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'identifier::'.
///
/// \param Context The AST context in which this nested-name-specifier
@@ -406,7 +406,7 @@ public:
void Extend(ASTContext &Context, IdentifierInfo *Identifier,
SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
- /// \brief Extend the current nested-name-specifier by another
+ /// Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'namespace::'.
///
/// \param Context The AST context in which this nested-name-specifier
@@ -420,7 +420,7 @@ public:
void Extend(ASTContext &Context, NamespaceDecl *Namespace,
SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
- /// \brief Extend the current nested-name-specifier by another
+ /// Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'namespace-alias::'.
///
/// \param Context The AST context in which this nested-name-specifier
@@ -435,11 +435,11 @@ public:
void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
SourceLocation AliasLoc, SourceLocation ColonColonLoc);
- /// \brief Turn this (empty) nested-name-specifier into the global
+ /// Turn this (empty) nested-name-specifier into the global
/// nested-name-specifier '::'.
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
- /// \brief Turns this (empty) nested-name-specifier into '__super'
+ /// Turns this (empty) nested-name-specifier into '__super'
/// nested-name-specifier.
///
/// \param Context The AST context in which this nested-name-specifier
@@ -455,7 +455,7 @@ public:
void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
SourceLocation SuperLoc, SourceLocation ColonColonLoc);
- /// \brief Make a new nested-name-specifier from incomplete source-location
+ /// Make a new nested-name-specifier from incomplete source-location
/// information.
///
/// This routine should be used very, very rarely, in cases where we
@@ -464,23 +464,23 @@ public:
void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
SourceRange R);
- /// \brief Adopt an existing nested-name-specifier (with source-range
+ /// Adopt an existing nested-name-specifier (with source-range
/// information).
void Adopt(NestedNameSpecifierLoc Other);
- /// \brief Retrieve the source range covered by this nested-name-specifier.
+ /// Retrieve the source range covered by this nested-name-specifier.
SourceRange getSourceRange() const LLVM_READONLY {
return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
}
- /// \brief Retrieve a nested-name-specifier with location information,
+ /// Retrieve a nested-name-specifier with location information,
/// copied into the given AST context.
///
/// \param Context The context into which this nested-name-specifier will be
/// copied.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
- /// \brief Retrieve a nested-name-specifier with location
+ /// Retrieve a nested-name-specifier with location
/// information based on the information in this builder.
///
/// This loc will contain references to the builder's internal data and may
@@ -489,14 +489,14 @@ public:
return NestedNameSpecifierLoc(Representation, Buffer);
}
- /// \brief Clear out this builder, and prepare it to build another
+ /// Clear out this builder, and prepare it to build another
/// nested-name-specifier with source-location information.
void Clear() {
Representation = nullptr;
BufferSize = 0;
}
- /// \brief Retrieve the underlying buffer.
+ /// Retrieve the underlying buffer.
///
/// \returns A pair containing a pointer to the buffer of source-location
/// data and the size of the source-location data that resides in that
diff --git a/include/clang/AST/NonTrivialTypeVisitor.h b/include/clang/AST/NonTrivialTypeVisitor.h
new file mode 100644
index 0000000000000..bab373dbb2986
--- /dev/null
+++ b/include/clang/AST/NonTrivialTypeVisitor.h
@@ -0,0 +1,113 @@
+//===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types *- 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 visitor classes that are used to traverse non-trivial
+// structs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H
+#define LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H
+
+#include "clang/AST/Type.h"
+
+namespace clang {
+
+template <class Derived, class RetTy = void> struct DestructedTypeVisitor {
+ template <class... Ts> RetTy visit(QualType FT, Ts &&... Args) {
+ return asDerived().visitWithKind(FT.isDestructedType(), FT,
+ std::forward<Ts>(Args)...);
+ }
+
+ template <class... Ts>
+ RetTy visitWithKind(QualType::DestructionKind DK, QualType FT,
+ Ts &&... Args) {
+ switch (DK) {
+ case QualType::DK_objc_strong_lifetime:
+ return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...);
+ case QualType::DK_nontrivial_c_struct:
+ return asDerived().visitStruct(FT, std::forward<Ts>(Args)...);
+ case QualType::DK_none:
+ return asDerived().visitTrivial(FT, std::forward<Ts>(Args)...);
+ case QualType::DK_cxx_destructor:
+ return asDerived().visitCXXDestructor(FT, std::forward<Ts>(Args)...);
+ case QualType::DK_objc_weak_lifetime:
+ return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...);
+ }
+
+ llvm_unreachable("unknown destruction kind");
+ }
+
+ Derived &asDerived() { return static_cast<Derived &>(*this); }
+};
+
+template <class Derived, class RetTy = void>
+struct DefaultInitializedTypeVisitor {
+ template <class... Ts> RetTy visit(QualType FT, Ts &&... Args) {
+ return asDerived().visitWithKind(
+ FT.isNonTrivialToPrimitiveDefaultInitialize(), FT,
+ std::forward<Ts>(Args)...);
+ }
+
+ template <class... Ts>
+ RetTy visitWithKind(QualType::PrimitiveDefaultInitializeKind PDIK,
+ QualType FT, Ts &&... Args) {
+ switch (PDIK) {
+ case QualType::PDIK_ARCStrong:
+ return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...);
+ case QualType::PDIK_ARCWeak:
+ return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...);
+ case QualType::PDIK_Struct:
+ return asDerived().visitStruct(FT, std::forward<Ts>(Args)...);
+ case QualType::PDIK_Trivial:
+ return asDerived().visitTrivial(FT, std::forward<Ts>(Args)...);
+ }
+
+ llvm_unreachable("unknown default-initialize kind");
+ }
+
+ Derived &asDerived() { return static_cast<Derived &>(*this); }
+};
+
+template <class Derived, bool IsMove, class RetTy = void>
+struct CopiedTypeVisitor {
+ template <class... Ts> RetTy visit(QualType FT, Ts &&... Args) {
+ QualType::PrimitiveCopyKind PCK =
+ IsMove ? FT.isNonTrivialToPrimitiveDestructiveMove()
+ : FT.isNonTrivialToPrimitiveCopy();
+ return asDerived().visitWithKind(PCK, FT, std::forward<Ts>(Args)...);
+ }
+
+ template <class... Ts>
+ RetTy visitWithKind(QualType::PrimitiveCopyKind PCK, QualType FT,
+ Ts &&... Args) {
+ asDerived().preVisit(PCK, FT, std::forward<Ts>(Args)...);
+
+ switch (PCK) {
+ case QualType::PCK_ARCStrong:
+ return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...);
+ case QualType::PCK_ARCWeak:
+ return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...);
+ case QualType::PCK_Struct:
+ return asDerived().visitStruct(FT, std::forward<Ts>(Args)...);
+ case QualType::PCK_Trivial:
+ return asDerived().visitTrivial(FT, std::forward<Ts>(Args)...);
+ case QualType::PCK_VolatileTrivial:
+ return asDerived().visitVolatileTrivial(FT, std::forward<Ts>(Args)...);
+ }
+
+ llvm_unreachable("unknown primitive copy kind");
+ }
+
+ Derived &asDerived() { return static_cast<Derived &>(*this); }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ODRHash.h b/include/clang/AST/ODRHash.h
index ed648bb8afb11..75b3617892110 100644
--- a/include/clang/AST/ODRHash.h
+++ b/include/clang/AST/ODRHash.h
@@ -37,9 +37,9 @@ class TemplateParameterList;
// Typically, only one Add* call is needed. clear can be called to reuse the
// object.
class ODRHash {
- // Use DenseMaps to convert between Decl and Type pointers and an index value.
- llvm::DenseMap<const Decl*, unsigned> DeclMap;
- llvm::DenseMap<const Type*, unsigned> TypeMap;
+ // Use DenseMaps to convert from DeclarationName and Type pointers
+ // to an index value.
+ llvm::DenseMap<DeclarationName, unsigned> DeclNameMap;
// Save space by processing bools at the end.
llvm::SmallVector<bool, 128> Bools;
@@ -54,8 +54,13 @@ public:
void AddCXXRecordDecl(const CXXRecordDecl *Record);
// Use this for ODR checking functions between modules. This method compares
+ // more information than the AddDecl class. SkipBody will process the
+ // hash as if the function has no body.
+ void AddFunctionDecl(const FunctionDecl *Function, bool SkipBody = false);
+
+ // Use this for ODR checking enums between modules. This method compares
// more information than the AddDecl class.
- void AddFunctionDecl(const FunctionDecl *Function);
+ void AddEnumDecl(const EnumDecl *Enum);
// Process SubDecls of the main Decl. This method calls the DeclVisitor
// while AddDecl does not.
@@ -82,7 +87,7 @@ public:
// Save booleans until the end to lower the size of data to process.
void AddBoolean(bool value);
- static bool isWhitelistedDecl(const Decl* D, const CXXRecordDecl *Record);
+ static bool isWhitelistedDecl(const Decl* D, const DeclContext *Parent);
};
} // end namespace clang
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index 1f732f67517a4..a28609f8cdf96 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief This file defines OpenMP AST classes for clauses.
+/// 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.
//
@@ -47,15 +47,15 @@ class ASTContext;
// AST classes for clauses.
//===----------------------------------------------------------------------===//
-/// \brief This is a basic class for representing single OpenMP clause.
+/// This is a basic class for representing single OpenMP clause.
class OMPClause {
- /// \brief Starting location of the clause (the clause keyword).
+ /// Starting location of the clause (the clause keyword).
SourceLocation StartLoc;
- /// \brief Ending location of the clause.
+ /// Ending location of the clause.
SourceLocation EndLoc;
- /// \brief Kind of the clause.
+ /// Kind of the clause.
OpenMPClauseKind Kind;
protected:
@@ -63,19 +63,19 @@ protected:
: StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {}
public:
- /// \brief Returns the starting location of the clause.
+ /// Returns the starting location of the clause.
SourceLocation getLocStart() const { return StartLoc; }
- /// \brief Returns the ending location of the clause.
+ /// Returns the ending location of the clause.
SourceLocation getLocEnd() const { return EndLoc; }
- /// \brief Sets the starting location of the clause.
+ /// Sets the starting location of the clause.
void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
- /// \brief Sets the ending location of the clause.
+ /// Sets the ending location of the clause.
void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
- /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.).
+ /// Returns kind of OpenMP clause (private, shared, reduction, etc.).
OpenMPClauseKind getClauseKind() const { return Kind; }
bool isImplicit() const { return StartLoc.isInvalid(); }
@@ -124,7 +124,7 @@ public:
Stmt *getPreInitStmt() { return PreInit; }
/// Get capture region for the stmt in the clause.
- OpenMPDirectiveKind getCaptureRegion() { return CaptureRegion; }
+ OpenMPDirectiveKind getCaptureRegion() const { return CaptureRegion; }
static OMPClauseWithPreInit *get(OMPClause *C);
static const OMPClauseWithPreInit *get(const OMPClause *C);
@@ -157,20 +157,20 @@ public:
static const OMPClauseWithPostUpdate *get(const OMPClause *C);
};
-/// \brief This represents clauses with the list of variables like 'private',
+/// 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 '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Number of variables in the list.
+ /// Number of variables in the list.
unsigned NumVars;
protected:
- /// \brief Build a clause with \a N variables
+ /// Build a clause with \a N variables
///
/// \param K Kind of the clause.
/// \param StartLoc Starting location of the clause (the clause keyword).
@@ -181,13 +181,13 @@ protected:
SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N)
: OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {}
- /// \brief Fetches list of variables associated with this clause.
+ /// Fetches list of variables associated with this clause.
MutableArrayRef<Expr *> getVarRefs() {
return MutableArrayRef<Expr *>(
static_cast<T *>(this)->template getTrailingObjects<Expr *>(), NumVars);
}
- /// \brief Sets the list of variables for this clause.
+ /// 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");
@@ -216,13 +216,13 @@ public:
varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); }
varlist_const_iterator varlist_end() const { return getVarRefs().end(); }
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Fetches list of all variables in the clause.
+ /// Fetches list of all variables in the clause.
ArrayRef<const Expr *> getVarRefs() const {
return llvm::makeArrayRef(
static_cast<const T *>(this)->template getTrailingObjects<Expr *>(),
@@ -230,7 +230,7 @@ public:
}
};
-/// \brief This represents 'if' clause in the '#pragma omp ...' directive.
+/// This represents 'if' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp parallel if(parallel:a > 5)
@@ -240,35 +240,35 @@ public:
class OMPIfClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Condition of the 'if' clause.
+ /// Condition of the 'if' clause.
Stmt *Condition = nullptr;
- /// \brief Location of ':' (if any).
+ /// Location of ':' (if any).
SourceLocation ColonLoc;
- /// \brief Directive name modifier for the clause.
+ /// Directive name modifier for the clause.
OpenMPDirectiveKind NameModifier = OMPD_unknown;
- /// \brief Name modifier location.
+ /// Name modifier location.
SourceLocation NameModifierLoc;
- /// \brief Set condition.
+ /// Set condition.
void setCondition(Expr *Cond) { Condition = Cond; }
- /// \brief Set directive name modifier for the clause.
+ /// Set directive name modifier for the clause.
void setNameModifier(OpenMPDirectiveKind NM) { NameModifier = NM; }
- /// \brief Set location of directive name modifier for the clause.
+ /// Set location of directive name modifier for the clause.
void setNameModifierLoc(SourceLocation Loc) { NameModifierLoc = Loc; }
- /// \brief Set location of ':'.
+ /// Set location of ':'.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
public:
- /// \brief Build 'if' clause with condition \a Cond.
+ /// Build 'if' clause with condition \a Cond.
///
/// \param NameModifier [OpenMP 4.1] Directive name modifier of clause.
/// \param Cond Condition of the clause.
@@ -290,27 +290,27 @@ public:
setPreInitStmt(HelperCond, CaptureRegion);
}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPIfClause()
: OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return the location of ':'.
+ /// Return the location of ':'.
SourceLocation getColonLoc() const { return ColonLoc; }
- /// \brief Returns condition.
+ /// Returns condition.
Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
- /// \brief Return directive name modifier associated with the clause.
+ /// Return directive name modifier associated with the clause.
OpenMPDirectiveKind getNameModifier() const { return NameModifier; }
- /// \brief Return the location of directive name modifier.
+ /// Return the location of directive name modifier.
SourceLocation getNameModifierLoc() const { return NameModifierLoc; }
child_range children() { return child_range(&Condition, &Condition + 1); }
@@ -320,7 +320,7 @@ public:
}
};
-/// \brief This represents 'final' clause in the '#pragma omp ...' directive.
+/// This represents 'final' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp task final(a > 5)
@@ -330,17 +330,17 @@ public:
class OMPFinalClause : public OMPClause {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Condition of the 'if' clause.
+ /// Condition of the 'if' clause.
Stmt *Condition = nullptr;
- /// \brief Set condition.
+ /// Set condition.
void setCondition(Expr *Cond) { Condition = Cond; }
public:
- /// \brief Build 'final' clause with condition \a Cond.
+ /// Build 'final' clause with condition \a Cond.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -351,17 +351,17 @@ public:
: OMPClause(OMPC_final, StartLoc, EndLoc), LParenLoc(LParenLoc),
Condition(Cond) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPFinalClause()
: OMPClause(OMPC_final, SourceLocation(), SourceLocation()) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Returns condition.
+ /// Returns condition.
Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
child_range children() { return child_range(&Condition, &Condition + 1); }
@@ -371,7 +371,7 @@ public:
}
};
-/// \brief This represents 'num_threads' clause in the '#pragma omp ...'
+/// This represents 'num_threads' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -382,17 +382,17 @@ public:
class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Condition of the 'num_threads' clause.
+ /// Condition of the 'num_threads' clause.
Stmt *NumThreads = nullptr;
- /// \brief Set condition.
+ /// Set condition.
void setNumThreads(Expr *NThreads) { NumThreads = NThreads; }
public:
- /// \brief Build 'num_threads' clause with condition \a NumThreads.
+ /// Build 'num_threads' clause with condition \a NumThreads.
///
/// \param NumThreads Number of threads for the construct.
/// \param HelperNumThreads Helper Number of threads for the construct.
@@ -411,18 +411,18 @@ public:
setPreInitStmt(HelperNumThreads, CaptureRegion);
}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPNumThreadsClause()
: OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Returns number of threads.
+ /// Returns number of threads.
Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); }
child_range children() { return child_range(&NumThreads, &NumThreads + 1); }
@@ -432,7 +432,7 @@ public:
}
};
-/// \brief This represents 'safelen' clause in the '#pragma omp ...'
+/// This represents 'safelen' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -447,17 +447,17 @@ public:
class OMPSafelenClause : public OMPClause {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Safe iteration space distance.
+ /// Safe iteration space distance.
Stmt *Safelen = nullptr;
- /// \brief Set safelen.
+ /// Set safelen.
void setSafelen(Expr *Len) { Safelen = Len; }
public:
- /// \brief Build 'safelen' clause.
+ /// Build 'safelen' clause.
///
/// \param Len Expression associated with this clause.
/// \param StartLoc Starting location of the clause.
@@ -467,17 +467,17 @@ public:
: OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc),
Safelen(Len) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
explicit OMPSafelenClause()
: OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return safe iteration space distance.
+ /// Return safe iteration space distance.
Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); }
child_range children() { return child_range(&Safelen, &Safelen + 1); }
@@ -487,7 +487,7 @@ public:
}
};
-/// \brief This represents 'simdlen' clause in the '#pragma omp ...'
+/// This represents 'simdlen' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -501,17 +501,17 @@ public:
class OMPSimdlenClause : public OMPClause {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Safe iteration space distance.
+ /// Safe iteration space distance.
Stmt *Simdlen = nullptr;
- /// \brief Set simdlen.
+ /// Set simdlen.
void setSimdlen(Expr *Len) { Simdlen = Len; }
public:
- /// \brief Build 'simdlen' clause.
+ /// Build 'simdlen' clause.
///
/// \param Len Expression associated with this clause.
/// \param StartLoc Starting location of the clause.
@@ -521,17 +521,17 @@ public:
: OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc),
Simdlen(Len) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
explicit OMPSimdlenClause()
: OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return safe iteration space distance.
+ /// Return safe iteration space distance.
Expr *getSimdlen() const { return cast_or_null<Expr>(Simdlen); }
child_range children() { return child_range(&Simdlen, &Simdlen + 1); }
@@ -541,7 +541,7 @@ public:
}
};
-/// \brief This represents 'collapse' clause in the '#pragma omp ...'
+/// This represents 'collapse' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -555,17 +555,17 @@ public:
class OMPCollapseClause : public OMPClause {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Number of for-loops.
+ /// Number of for-loops.
Stmt *NumForLoops = nullptr;
- /// \brief Set the number of associated for-loops.
+ /// Set the number of associated for-loops.
void setNumForLoops(Expr *Num) { NumForLoops = Num; }
public:
- /// \brief Build 'collapse' clause.
+ /// Build 'collapse' clause.
///
/// \param Num Expression associated with this clause.
/// \param StartLoc Starting location of the clause.
@@ -576,17 +576,17 @@ public:
: OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc),
NumForLoops(Num) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
explicit OMPCollapseClause()
: OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return the number of associated for-loops.
+ /// Return the number of associated for-loops.
Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
@@ -596,7 +596,7 @@ public:
}
};
-/// \brief This represents 'default' clause in the '#pragma omp ...' directive.
+/// This represents 'default' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp parallel default(shared)
@@ -606,27 +606,27 @@ public:
class OMPDefaultClause : public OMPClause {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief A kind of the 'default' clause.
+ /// A kind of the 'default' clause.
OpenMPDefaultClauseKind Kind = OMPC_DEFAULT_unknown;
- /// \brief Start location of the kind in source code.
+ /// Start location of the kind in source code.
SourceLocation KindKwLoc;
- /// \brief Set kind of the clauses.
+ /// Set kind of the clauses.
///
/// \param K Argument of clause.
void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
- /// \brief Set argument location.
+ /// 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').
+ /// 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.
@@ -639,20 +639,20 @@ public:
: OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc),
Kind(A), KindKwLoc(ALoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPDefaultClause()
: OMPClause(OMPC_default, SourceLocation(), SourceLocation()) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Returns kind of the clause.
+ /// Returns kind of the clause.
OpenMPDefaultClauseKind getDefaultKind() const { return Kind; }
- /// \brief Returns location of clause kind.
+ /// Returns location of clause kind.
SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
child_range children() {
@@ -664,7 +664,7 @@ public:
}
};
-/// \brief This represents 'proc_bind' clause in the '#pragma omp ...'
+/// This represents 'proc_bind' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -675,27 +675,27 @@ public:
class OMPProcBindClause : public OMPClause {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief A kind of the 'proc_bind' clause.
+ /// A kind of the 'proc_bind' clause.
OpenMPProcBindClauseKind Kind = OMPC_PROC_BIND_unknown;
- /// \brief Start location of the kind in source code.
+ /// Start location of the kind in source code.
SourceLocation KindKwLoc;
- /// \brief Set kind of the clause.
+ /// Set kind of the clause.
///
/// \param K Kind of clause.
void setProcBindKind(OpenMPProcBindClauseKind K) { Kind = K; }
- /// \brief Set clause kind location.
+ /// 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
+ /// Build 'proc_bind' clause with argument \a A ('master', 'close' or
/// 'spread').
///
/// \param A Argument of the clause ('master', 'close' or 'spread').
@@ -709,20 +709,20 @@ public:
: OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
Kind(A), KindKwLoc(ALoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPProcBindClause()
: OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Returns kind of the clause.
+ /// Returns kind of the clause.
OpenMPProcBindClauseKind getProcBindKind() const { return Kind; }
- /// \brief Returns location of clause kind.
+ /// Returns location of clause kind.
SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; }
child_range children() {
@@ -734,7 +734,7 @@ public:
}
};
-/// \brief This represents 'schedule' clause in the '#pragma omp ...' directive.
+/// This represents 'schedule' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp for schedule(static, 3)
@@ -744,58 +744,58 @@ public:
class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief A kind of the 'schedule' clause.
+ /// A kind of the 'schedule' clause.
OpenMPScheduleClauseKind Kind = OMPC_SCHEDULE_unknown;
- /// \brief Modifiers for 'schedule' clause.
+ /// Modifiers for 'schedule' clause.
enum {FIRST, SECOND, NUM_MODIFIERS};
OpenMPScheduleClauseModifier Modifiers[NUM_MODIFIERS];
- /// \brief Locations of modifiers.
+ /// Locations of modifiers.
SourceLocation ModifiersLoc[NUM_MODIFIERS];
- /// \brief Start location of the schedule ind in source code.
+ /// Start location of the schedule ind in source code.
SourceLocation KindLoc;
- /// \brief Location of ',' (if any).
+ /// Location of ',' (if any).
SourceLocation CommaLoc;
- /// \brief Chunk size.
+ /// Chunk size.
Expr *ChunkSize = nullptr;
- /// \brief Set schedule kind.
+ /// Set schedule kind.
///
/// \param K Schedule kind.
void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; }
- /// \brief Set the first schedule modifier.
+ /// Set the first schedule modifier.
///
/// \param M Schedule modifier.
void setFirstScheduleModifier(OpenMPScheduleClauseModifier M) {
Modifiers[FIRST] = M;
}
- /// \brief Set the second schedule modifier.
+ /// Set the second schedule modifier.
///
/// \param M Schedule modifier.
void setSecondScheduleModifier(OpenMPScheduleClauseModifier M) {
Modifiers[SECOND] = M;
}
- /// \brief Set location of the first schedule modifier.
+ /// Set location of the first schedule modifier.
void setFirstScheduleModifierLoc(SourceLocation Loc) {
ModifiersLoc[FIRST] = Loc;
}
- /// \brief Set location of the second schedule modifier.
+ /// Set location of the second schedule modifier.
void setSecondScheduleModifierLoc(SourceLocation Loc) {
ModifiersLoc[SECOND] = Loc;
}
- /// \brief Set schedule modifier location.
+ /// Set schedule modifier location.
///
/// \param M Schedule modifier location.
void setScheduleModifer(OpenMPScheduleClauseModifier M) {
@@ -807,28 +807,28 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit {
}
}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
///
/// \param Loc Location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Set schedule kind start location.
+ /// Set schedule kind start location.
///
/// \param KLoc Schedule kind location.
void setScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
- /// \brief Set location of ','.
+ /// Set location of ','.
///
/// \param Loc Location of ','.
void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; }
- /// \brief Set chunk size.
+ /// 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
+ /// Build 'schedule' clause with schedule kind \a Kind and chunk size
/// expression \a ChunkSize.
///
/// \param StartLoc Starting location of the clause.
@@ -859,7 +859,7 @@ public:
ModifiersLoc[SECOND] = M2Loc;
}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
explicit OMPScheduleClause()
: OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this) {
@@ -867,42 +867,42 @@ public:
Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown;
}
- /// \brief Get kind of the clause.
+ /// Get kind of the clause.
OpenMPScheduleClauseKind getScheduleKind() const { return Kind; }
- /// \brief Get the first modifier of the clause.
+ /// Get the first modifier of the clause.
OpenMPScheduleClauseModifier getFirstScheduleModifier() const {
return Modifiers[FIRST];
}
- /// \brief Get the second modifier of the clause.
+ /// Get the second modifier of the clause.
OpenMPScheduleClauseModifier getSecondScheduleModifier() const {
return Modifiers[SECOND];
}
- /// \brief Get location of '('.
+ /// Get location of '('.
SourceLocation getLParenLoc() { return LParenLoc; }
- /// \brief Get kind location.
+ /// Get kind location.
SourceLocation getScheduleKindLoc() { return KindLoc; }
- /// \brief Get the first modifier location.
+ /// Get the first modifier location.
SourceLocation getFirstScheduleModifierLoc() const {
return ModifiersLoc[FIRST];
}
- /// \brief Get the second modifier location.
+ /// Get the second modifier location.
SourceLocation getSecondScheduleModifierLoc() const {
return ModifiersLoc[SECOND];
}
- /// \brief Get location of ','.
+ /// Get location of ','.
SourceLocation getCommaLoc() { return CommaLoc; }
- /// \brief Get chunk size.
+ /// Get chunk size.
Expr *getChunkSize() { return ChunkSize; }
- /// \brief Get chunk size.
+ /// Get chunk size.
const Expr *getChunkSize() const { return ChunkSize; }
child_range children() {
@@ -915,7 +915,7 @@ public:
}
};
-/// \brief This represents 'ordered' clause in the '#pragma omp ...' directive.
+/// This represents 'ordered' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp for ordered (2)
@@ -925,17 +925,17 @@ public:
class OMPOrderedClause : public OMPClause {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Number of for-loops.
+ /// Number of for-loops.
Stmt *NumForLoops = nullptr;
- /// \brief Set the number of associated for-loops.
+ /// Set the number of associated for-loops.
void setNumForLoops(Expr *Num) { NumForLoops = Num; }
public:
- /// \brief Build 'ordered' clause.
+ /// Build 'ordered' clause.
///
/// \param Num Expression, possibly associated with this clause.
/// \param StartLoc Starting location of the clause.
@@ -946,17 +946,17 @@ public:
: OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc),
NumForLoops(Num) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
explicit OMPOrderedClause()
: OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return the number of associated for-loops.
+ /// Return the number of associated for-loops.
Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
@@ -966,7 +966,7 @@ public:
}
};
-/// \brief This represents 'nowait' clause in the '#pragma omp ...' directive.
+/// This represents 'nowait' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp for nowait
@@ -974,14 +974,14 @@ public:
/// In this example directive '#pragma omp for' has 'nowait' clause.
class OMPNowaitClause : public OMPClause {
public:
- /// \brief Build 'nowait' clause.
+ /// 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.
+ /// Build an empty clause.
OMPNowaitClause()
: OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {}
@@ -994,7 +994,7 @@ public:
}
};
-/// \brief This represents 'untied' clause in the '#pragma omp ...' directive.
+/// This represents 'untied' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp task untied
@@ -1002,14 +1002,14 @@ public:
/// In this example directive '#pragma omp task' has 'untied' clause.
class OMPUntiedClause : public OMPClause {
public:
- /// \brief Build 'untied' clause.
+ /// 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.
+ /// Build an empty clause.
OMPUntiedClause()
: OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {}
@@ -1022,7 +1022,7 @@ public:
}
};
-/// \brief This represents 'mergeable' clause in the '#pragma omp ...'
+/// This represents 'mergeable' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -1031,14 +1031,14 @@ public:
/// In this example directive '#pragma omp task' has 'mergeable' clause.
class OMPMergeableClause : public OMPClause {
public:
- /// \brief Build 'mergeable' clause.
+ /// 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.
+ /// Build an empty clause.
OMPMergeableClause()
: OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {}
@@ -1051,7 +1051,7 @@ public:
}
};
-/// \brief This represents 'read' clause in the '#pragma omp atomic' directive.
+/// This represents 'read' clause in the '#pragma omp atomic' directive.
///
/// \code
/// #pragma omp atomic read
@@ -1059,14 +1059,14 @@ public:
/// In this example directive '#pragma omp atomic' has 'read' clause.
class OMPReadClause : public OMPClause {
public:
- /// \brief Build 'read' clause.
+ /// Build 'read' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_read, StartLoc, EndLoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {}
child_range children() {
@@ -1078,7 +1078,7 @@ public:
}
};
-/// \brief This represents 'write' clause in the '#pragma omp atomic' directive.
+/// This represents 'write' clause in the '#pragma omp atomic' directive.
///
/// \code
/// #pragma omp atomic write
@@ -1086,14 +1086,14 @@ public:
/// In this example directive '#pragma omp atomic' has 'write' clause.
class OMPWriteClause : public OMPClause {
public:
- /// \brief Build 'write' clause.
+ /// Build 'write' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_write, StartLoc, EndLoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPWriteClause()
: OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {}
@@ -1106,7 +1106,7 @@ public:
}
};
-/// \brief This represents 'update' clause in the '#pragma omp atomic'
+/// This represents 'update' clause in the '#pragma omp atomic'
/// directive.
///
/// \code
@@ -1115,14 +1115,14 @@ public:
/// In this example directive '#pragma omp atomic' has 'update' clause.
class OMPUpdateClause : public OMPClause {
public:
- /// \brief Build 'update' clause.
+ /// Build 'update' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_update, StartLoc, EndLoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPUpdateClause()
: OMPClause(OMPC_update, SourceLocation(), SourceLocation()) {}
@@ -1135,7 +1135,7 @@ public:
}
};
-/// \brief This represents 'capture' clause in the '#pragma omp atomic'
+/// This represents 'capture' clause in the '#pragma omp atomic'
/// directive.
///
/// \code
@@ -1144,14 +1144,14 @@ public:
/// In this example directive '#pragma omp atomic' has 'capture' clause.
class OMPCaptureClause : public OMPClause {
public:
- /// \brief Build 'capture' clause.
+ /// Build 'capture' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_capture, StartLoc, EndLoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPCaptureClause()
: OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {}
@@ -1164,7 +1164,7 @@ public:
}
};
-/// \brief This represents 'seq_cst' clause in the '#pragma omp atomic'
+/// This represents 'seq_cst' clause in the '#pragma omp atomic'
/// directive.
///
/// \code
@@ -1173,14 +1173,14 @@ public:
/// In this example directive '#pragma omp atomic' has 'seq_cst' clause.
class OMPSeqCstClause : public OMPClause {
public:
- /// \brief Build 'seq_cst' clause.
+ /// Build 'seq_cst' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_seq_cst, StartLoc, EndLoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPSeqCstClause()
: OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {}
@@ -1193,7 +1193,7 @@ public:
}
};
-/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
+/// This represents clause 'private' in the '#pragma omp ...' directives.
///
/// \code
/// #pragma omp parallel private(a,b)
@@ -1207,7 +1207,7 @@ class OMPPrivateClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Build clause with number of variables \a N.
+ /// Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -1218,7 +1218,7 @@ class OMPPrivateClause final
: OMPVarListClause<OMPPrivateClause>(OMPC_private, StartLoc, LParenLoc,
EndLoc, N) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPPrivateClause(unsigned N)
@@ -1226,12 +1226,12 @@ class OMPPrivateClause final
SourceLocation(), SourceLocation(),
N) {}
- /// \brief Sets the list of references to private copies with initializers for
+ /// Sets the list of references to private copies with initializers for
/// new private variables.
/// \param VL List of references.
void setPrivateCopies(ArrayRef<Expr *> VL);
- /// \brief Gets the list of references to private copies with initializers for
+ /// Gets the list of references to private copies with initializers for
/// new private variables.
MutableArrayRef<Expr *> getPrivateCopies() {
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
@@ -1241,7 +1241,7 @@ class OMPPrivateClause final
}
public:
- /// \brief Creates clause with a list of variables \a VL.
+ /// Creates clause with a list of variables \a VL.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
@@ -1254,7 +1254,7 @@ public:
SourceLocation EndLoc, ArrayRef<Expr *> VL,
ArrayRef<Expr *> PrivateVL);
- /// \brief Creates an empty clause with the place for \a N variables.
+ /// Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
@@ -1286,7 +1286,7 @@ public:
}
};
-/// \brief This represents clause 'firstprivate' in the '#pragma omp ...'
+/// This represents clause 'firstprivate' in the '#pragma omp ...'
/// directives.
///
/// \code
@@ -1302,7 +1302,7 @@ class OMPFirstprivateClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Build clause with number of variables \a N.
+ /// Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -1314,7 +1314,7 @@ class OMPFirstprivateClause final
LParenLoc, EndLoc, N),
OMPClauseWithPreInit(this) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPFirstprivateClause(unsigned N)
@@ -1323,12 +1323,12 @@ class OMPFirstprivateClause final
SourceLocation(), N),
OMPClauseWithPreInit(this) {}
- /// \brief Sets the list of references to private copies with initializers for
+ /// Sets the list of references to private copies with initializers for
/// new private variables.
/// \param VL List of references.
void setPrivateCopies(ArrayRef<Expr *> VL);
- /// \brief Gets the list of references to private copies with initializers for
+ /// Gets the list of references to private copies with initializers for
/// new private variables.
MutableArrayRef<Expr *> getPrivateCopies() {
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
@@ -1337,12 +1337,12 @@ class OMPFirstprivateClause final
return llvm::makeArrayRef(varlist_end(), varlist_size());
}
- /// \brief Sets the list of references to initializer variables for new
+ /// Sets the list of references to initializer variables for new
/// private variables.
/// \param VL List of references.
void setInits(ArrayRef<Expr *> VL);
- /// \brief Gets the list of references to initializer variables for new
+ /// Gets the list of references to initializer variables for new
/// private variables.
MutableArrayRef<Expr *> getInits() {
return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
@@ -1352,7 +1352,7 @@ class OMPFirstprivateClause final
}
public:
- /// \brief Creates clause with a list of variables \a VL.
+ /// Creates clause with a list of variables \a VL.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
@@ -1370,7 +1370,7 @@ public:
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
ArrayRef<Expr *> InitVL, Stmt *PreInit);
- /// \brief Creates an empty clause with the place for \a N variables.
+ /// Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
@@ -1413,7 +1413,7 @@ public:
}
};
-/// \brief This represents clause 'lastprivate' in the '#pragma omp ...'
+/// This represents clause 'lastprivate' in the '#pragma omp ...'
/// directives.
///
/// \code
@@ -1445,7 +1445,7 @@ class OMPLastprivateClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Build clause with number of variables \a N.
+ /// Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -1457,7 +1457,7 @@ class OMPLastprivateClause final
LParenLoc, EndLoc, N),
OMPClauseWithPostUpdate(this) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPLastprivateClause(unsigned N)
@@ -1466,7 +1466,7 @@ class OMPLastprivateClause final
SourceLocation(), N),
OMPClauseWithPostUpdate(this) {}
- /// \brief Get the list of helper expressions for initialization of private
+ /// Get the list of helper expressions for initialization of private
/// copies for lastprivate variables.
MutableArrayRef<Expr *> getPrivateCopies() {
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
@@ -1475,13 +1475,13 @@ class OMPLastprivateClause final
return llvm::makeArrayRef(varlist_end(), varlist_size());
}
- /// \brief Set list of helper expressions, required for proper codegen of the
+ /// Set list of helper expressions, required for proper codegen of the
/// clause. These expressions represent private variables (for arrays, single
/// array element) in the final assignment statement performed by the
/// lastprivate clause.
void setSourceExprs(ArrayRef<Expr *> SrcExprs);
- /// \brief Get the list of helper source expressions.
+ /// Get the list of helper source expressions.
MutableArrayRef<Expr *> getSourceExprs() {
return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
}
@@ -1489,13 +1489,13 @@ class OMPLastprivateClause final
return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
}
- /// \brief Set list of helper expressions, required for proper codegen of the
+ /// Set list of helper expressions, required for proper codegen of the
/// clause. These expressions represent original variables (for arrays, single
/// array element) in the final assignment statement performed by the
/// lastprivate clause.
void setDestinationExprs(ArrayRef<Expr *> DstExprs);
- /// \brief Get the list of helper destination expressions.
+ /// Get the list of helper destination expressions.
MutableArrayRef<Expr *> getDestinationExprs() {
return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
}
@@ -1503,12 +1503,12 @@ class OMPLastprivateClause final
return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
}
- /// \brief Set list of helper assignment expressions, required for proper
+ /// Set list of helper assignment expressions, required for proper
/// codegen of the clause. These expressions are assignment expressions that
/// assign private copy of the variable to original variable.
void setAssignmentOps(ArrayRef<Expr *> AssignmentOps);
- /// \brief Get the list of helper assignment expressions.
+ /// Get the list of helper assignment expressions.
MutableArrayRef<Expr *> getAssignmentOps() {
return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
}
@@ -1517,7 +1517,7 @@ class OMPLastprivateClause final
}
public:
- /// \brief Creates clause with a list of variables \a VL.
+ /// Creates clause with a list of variables \a VL.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
@@ -1547,7 +1547,7 @@ public:
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,
Stmt *PreInit, Expr *PostUpdate);
- /// \brief Creates an empty clause with the place for \a N variables.
+ /// Creates an empty clause with the place for \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
@@ -1559,7 +1559,7 @@ public:
using helper_expr_const_range =
llvm::iterator_range<helper_expr_const_iterator>;
- /// \brief Set list of helper expressions, required for generation of private
+ /// Set list of helper expressions, required for generation of private
/// copies of original lastprivate variables.
void setPrivateCopies(ArrayRef<Expr *> PrivateCopies);
@@ -1612,7 +1612,7 @@ public:
}
};
-/// \brief This represents clause 'shared' in the '#pragma omp ...' directives.
+/// This represents clause 'shared' in the '#pragma omp ...' directives.
///
/// \code
/// #pragma omp parallel shared(a,b)
@@ -1625,7 +1625,7 @@ class OMPSharedClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Build clause with number of variables \a N.
+ /// Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -1636,7 +1636,7 @@ class OMPSharedClause final
: OMPVarListClause<OMPSharedClause>(OMPC_shared, StartLoc, LParenLoc,
EndLoc, N) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPSharedClause(unsigned N)
@@ -1645,7 +1645,7 @@ class OMPSharedClause final
N) {}
public:
- /// \brief Creates clause with a list of variables \a VL.
+ /// Creates clause with a list of variables \a VL.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
@@ -1656,7 +1656,7 @@ public:
SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL);
- /// \brief Creates an empty clause with \a N variables.
+ /// Creates an empty clause with \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
@@ -1672,7 +1672,7 @@ public:
}
};
-/// \brief This represents clause 'reduction' in the '#pragma omp ...'
+/// This represents clause 'reduction' in the '#pragma omp ...'
/// directives.
///
/// \code
@@ -1688,16 +1688,16 @@ class OMPReductionClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Location of ':'.
+ /// Location of ':'.
SourceLocation ColonLoc;
- /// \brief Nested name specifier for C++.
+ /// Nested name specifier for C++.
NestedNameSpecifierLoc QualifierLoc;
- /// \brief Name of custom operator.
+ /// Name of custom operator.
DeclarationNameInfo NameInfo;
- /// \brief Build clause with number of variables \a N.
+ /// Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -1715,7 +1715,7 @@ class OMPReductionClause final
OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc),
QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPReductionClause(unsigned N)
@@ -1724,21 +1724,21 @@ class OMPReductionClause final
N),
OMPClauseWithPostUpdate(this) {}
- /// \brief Sets location of ':' symbol in clause.
+ /// Sets location of ':' symbol in clause.
void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
- /// \brief Sets the name info for specified reduction identifier.
+ /// Sets the name info for specified reduction identifier.
void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }
- /// \brief Sets the nested name specifier.
+ /// Sets the nested name specifier.
void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }
- /// \brief Set list of helper expressions, required for proper codegen of the
+ /// Set list of helper expressions, required for proper codegen of the
/// clause. These expressions represent private copy of the reduction
/// variable.
void setPrivates(ArrayRef<Expr *> Privates);
- /// \brief Get the list of helper privates.
+ /// Get the list of helper privates.
MutableArrayRef<Expr *> getPrivates() {
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
@@ -1746,12 +1746,12 @@ class OMPReductionClause final
return llvm::makeArrayRef(varlist_end(), varlist_size());
}
- /// \brief Set list of helper expressions, required for proper codegen of the
+ /// Set list of helper expressions, required for proper codegen of the
/// clause. These expressions represent LHS expression in the final
/// reduction expression performed by the reduction clause.
void setLHSExprs(ArrayRef<Expr *> LHSExprs);
- /// \brief Get the list of helper LHS expressions.
+ /// Get the list of helper LHS expressions.
MutableArrayRef<Expr *> getLHSExprs() {
return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
}
@@ -1759,14 +1759,14 @@ class OMPReductionClause final
return llvm::makeArrayRef(getPrivates().end(), varlist_size());
}
- /// \brief Set list of helper expressions, required for proper codegen of the
+ /// Set list of helper expressions, required for proper codegen of the
/// clause. These expressions represent RHS expression in the final
/// reduction expression performed by the reduction clause.
/// Also, variables in these expressions are used for proper initialization of
/// reduction copies.
void setRHSExprs(ArrayRef<Expr *> RHSExprs);
- /// \brief Get the list of helper destination expressions.
+ /// Get the list of helper destination expressions.
MutableArrayRef<Expr *> getRHSExprs() {
return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
}
@@ -1774,13 +1774,13 @@ class OMPReductionClause final
return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
}
- /// \brief Set list of helper reduction expressions, required for proper
+ /// Set list of helper reduction expressions, required for proper
/// codegen of the clause. These expressions are binary expressions or
/// operator/custom reduction call that calculates new value from source
/// helper expressions to destination helper expressions.
void setReductionOps(ArrayRef<Expr *> ReductionOps);
- /// \brief Get the list of helper reduction expressions.
+ /// Get the list of helper reduction expressions.
MutableArrayRef<Expr *> getReductionOps() {
return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
}
@@ -1789,7 +1789,7 @@ class OMPReductionClause final
}
public:
- /// \brief Creates clause with a list of variables \a VL.
+ /// Creates clause with a list of variables \a VL.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -1829,19 +1829,19 @@ public:
ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs,
ArrayRef<Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate);
- /// \brief Creates an empty clause with the place for \a N variables.
+ /// 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.
+ /// Gets location of ':' symbol in clause.
SourceLocation getColonLoc() const { return ColonLoc; }
- /// \brief Gets the name info for specified reduction identifier.
+ /// Gets the name info for specified reduction identifier.
const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
- /// \brief Gets the nested name specifier.
+ /// Gets the nested name specifier.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
@@ -2357,7 +2357,7 @@ public:
}
};
-/// \brief This represents clause 'linear' in the '#pragma omp ...'
+/// This represents clause 'linear' in the '#pragma omp ...'
/// directives.
///
/// \code
@@ -2373,22 +2373,22 @@ class OMPLinearClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Modifier of 'linear' clause.
+ /// Modifier of 'linear' clause.
OpenMPLinearClauseKind Modifier = OMPC_LINEAR_val;
- /// \brief Location of linear modifier if any.
+ /// Location of linear modifier if any.
SourceLocation ModifierLoc;
- /// \brief Location of ':'.
+ /// Location of ':'.
SourceLocation ColonLoc;
- /// \brief Sets the linear step for clause.
+ /// Sets the linear step for clause.
void setStep(Expr *Step) { *(getFinals().end()) = Step; }
- /// \brief Sets the expression to calculate linear step for clause.
+ /// Sets the expression to calculate linear step for clause.
void setCalcStep(Expr *CalcStep) { *(getFinals().end() + 1) = CalcStep; }
- /// \brief Build 'linear' clause with given number of variables \a NumVars.
+ /// Build 'linear' clause with given number of variables \a NumVars.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -2404,7 +2404,7 @@ class OMPLinearClause final
OMPClauseWithPostUpdate(this), Modifier(Modifier),
ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param NumVars Number of variables.
explicit OMPLinearClause(unsigned NumVars)
@@ -2413,7 +2413,7 @@ class OMPLinearClause final
NumVars),
OMPClauseWithPostUpdate(this) {}
- /// \brief Gets the list of initial values for linear variables.
+ /// Gets the list of initial values for linear variables.
///
/// There are NumVars expressions with initial values allocated after the
/// varlist, they are followed by NumVars update expressions (used to update
@@ -2439,7 +2439,7 @@ class OMPLinearClause final
return llvm::makeArrayRef(getPrivates().end(), varlist_size());
}
- /// \brief Sets the list of update expressions for linear variables.
+ /// Sets the list of update expressions for linear variables.
MutableArrayRef<Expr *> getUpdates() {
return MutableArrayRef<Expr *>(getInits().end(), varlist_size());
}
@@ -2447,7 +2447,7 @@ class OMPLinearClause final
return llvm::makeArrayRef(getInits().end(), varlist_size());
}
- /// \brief Sets the list of final update expressions for linear variables.
+ /// Sets the list of final update expressions for linear variables.
MutableArrayRef<Expr *> getFinals() {
return MutableArrayRef<Expr *>(getUpdates().end(), varlist_size());
}
@@ -2455,16 +2455,16 @@ class OMPLinearClause final
return llvm::makeArrayRef(getUpdates().end(), varlist_size());
}
- /// \brief Sets the list of the copies of original linear variables.
+ /// Sets the list of the copies of original linear variables.
/// \param PL List of expressions.
void setPrivates(ArrayRef<Expr *> PL);
- /// \brief Sets the list of the initial values for linear variables.
+ /// Sets the list of the initial values for linear variables.
/// \param IL List of expressions.
void setInits(ArrayRef<Expr *> IL);
public:
- /// \brief Creates clause with a list of variables \a VL and a linear step
+ /// Creates clause with a list of variables \a VL and a linear step
/// \a Step.
///
/// \param C AST Context.
@@ -2490,47 +2490,47 @@ public:
ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep,
Stmt *PreInit, Expr *PostUpdate);
- /// \brief Creates an empty clause with the place for \a NumVars variables.
+ /// 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 Set modifier.
+ /// Set modifier.
void setModifier(OpenMPLinearClauseKind Kind) { Modifier = Kind; }
- /// \brief Return modifier.
+ /// Return modifier.
OpenMPLinearClauseKind getModifier() const { return Modifier; }
- /// \brief Set modifier location.
+ /// Set modifier location.
void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }
- /// \brief Return modifier location.
+ /// Return modifier location.
SourceLocation getModifierLoc() const { return ModifierLoc; }
- /// \brief Sets the location of ':'.
+ /// Sets the location of ':'.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
- /// \brief Returns the location of ':'.
+ /// Returns the location of ':'.
SourceLocation getColonLoc() const { return ColonLoc; }
- /// \brief Returns linear step.
+ /// Returns linear step.
Expr *getStep() { return *(getFinals().end()); }
- /// \brief Returns linear step.
+ /// Returns linear step.
const Expr *getStep() const { return *(getFinals().end()); }
- /// \brief Returns expression to calculate linear step.
+ /// Returns expression to calculate linear step.
Expr *getCalcStep() { return *(getFinals().end() + 1); }
- /// \brief Returns expression to calculate linear step.
+ /// Returns expression to calculate linear step.
const Expr *getCalcStep() const { return *(getFinals().end() + 1); }
- /// \brief Sets the list of update expressions for linear variables.
+ /// Sets the list of update expressions for linear variables.
/// \param UL List of expressions.
void setUpdates(ArrayRef<Expr *> UL);
- /// \brief Sets the list of final update expressions for linear variables.
+ /// Sets the list of final update expressions for linear variables.
/// \param FL List of expressions.
void setFinals(ArrayRef<Expr *> FL);
@@ -2596,7 +2596,7 @@ public:
}
};
-/// \brief This represents clause 'aligned' in the '#pragma omp ...'
+/// This represents clause 'aligned' in the '#pragma omp ...'
/// directives.
///
/// \code
@@ -2611,13 +2611,13 @@ class OMPAlignedClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Location of ':'.
+ /// Location of ':'.
SourceLocation ColonLoc;
- /// \brief Sets the alignment for clause.
+ /// Sets the alignment for clause.
void setAlignment(Expr *A) { *varlist_end() = A; }
- /// \brief Build 'aligned' clause with given number of variables \a NumVars.
+ /// Build 'aligned' clause with given number of variables \a NumVars.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -2631,7 +2631,7 @@ class OMPAlignedClause final
EndLoc, NumVars),
ColonLoc(ColonLoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param NumVars Number of variables.
explicit OMPAlignedClause(unsigned NumVars)
@@ -2640,7 +2640,7 @@ class OMPAlignedClause final
NumVars) {}
public:
- /// \brief Creates clause with a list of variables \a VL and alignment \a A.
+ /// Creates clause with a list of variables \a VL and alignment \a A.
///
/// \param C AST Context.
/// \param StartLoc Starting location of the clause.
@@ -2655,22 +2655,22 @@ public:
SourceLocation EndLoc, ArrayRef<Expr *> VL,
Expr *A);
- /// \brief Creates an empty clause with the place for \a NumVars variables.
+ /// 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 ':'.
+ /// Sets the location of ':'.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
- /// \brief Returns the location of ':'.
+ /// Returns the location of ':'.
SourceLocation getColonLoc() const { return ColonLoc; }
- /// \brief Returns alignment.
+ /// Returns alignment.
Expr *getAlignment() { return *varlist_end(); }
- /// \brief Returns alignment.
+ /// Returns alignment.
const Expr *getAlignment() const { return *varlist_end(); }
child_range children() {
@@ -2683,7 +2683,7 @@ public:
}
};
-/// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
+/// This represents clause 'copyin' in the '#pragma omp ...' directives.
///
/// \code
/// #pragma omp parallel copyin(a,b)
@@ -2710,7 +2710,7 @@ class OMPCopyinClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Build clause with number of variables \a N.
+ /// Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -2721,7 +2721,7 @@ class OMPCopyinClause final
: OMPVarListClause<OMPCopyinClause>(OMPC_copyin, StartLoc, LParenLoc,
EndLoc, N) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPCopyinClause(unsigned N)
@@ -2729,12 +2729,12 @@ class OMPCopyinClause final
SourceLocation(), SourceLocation(),
N) {}
- /// \brief Set list of helper expressions, required for proper codegen of the
+ /// Set list of helper expressions, required for proper codegen of the
/// clause. These expressions represent source expression in the final
/// assignment statement performed by the copyin clause.
void setSourceExprs(ArrayRef<Expr *> SrcExprs);
- /// \brief Get the list of helper source expressions.
+ /// Get the list of helper source expressions.
MutableArrayRef<Expr *> getSourceExprs() {
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
@@ -2742,12 +2742,12 @@ class OMPCopyinClause final
return llvm::makeArrayRef(varlist_end(), varlist_size());
}
- /// \brief Set list of helper expressions, required for proper codegen of the
+ /// Set list of helper expressions, required for proper codegen of the
/// clause. These expressions represent destination expression in the final
/// assignment statement performed by the copyin clause.
void setDestinationExprs(ArrayRef<Expr *> DstExprs);
- /// \brief Get the list of helper destination expressions.
+ /// Get the list of helper destination expressions.
MutableArrayRef<Expr *> getDestinationExprs() {
return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
}
@@ -2755,13 +2755,13 @@ class OMPCopyinClause final
return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
}
- /// \brief Set list of helper assignment expressions, required for proper
+ /// Set list of helper assignment expressions, required for proper
/// codegen of the clause. These expressions are assignment expressions that
/// assign source helper expressions to destination helper expressions
/// correspondingly.
void setAssignmentOps(ArrayRef<Expr *> AssignmentOps);
- /// \brief Get the list of helper assignment expressions.
+ /// Get the list of helper assignment expressions.
MutableArrayRef<Expr *> getAssignmentOps() {
return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
}
@@ -2770,7 +2770,7 @@ class OMPCopyinClause final
}
public:
- /// \brief Creates clause with a list of variables \a VL.
+ /// Creates clause with a list of variables \a VL.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
@@ -2796,7 +2796,7 @@ public:
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps);
- /// \brief Creates an empty clause with \a N variables.
+ /// Creates an empty clause with \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
@@ -2847,7 +2847,7 @@ public:
}
};
-/// \brief This represents clause 'copyprivate' in the '#pragma omp ...'
+/// This represents clause 'copyprivate' in the '#pragma omp ...'
/// directives.
///
/// \code
@@ -2862,7 +2862,7 @@ class OMPCopyprivateClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Build clause with number of variables \a N.
+ /// Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -2873,7 +2873,7 @@ class OMPCopyprivateClause final
: OMPVarListClause<OMPCopyprivateClause>(OMPC_copyprivate, StartLoc,
LParenLoc, EndLoc, N) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPCopyprivateClause(unsigned N)
@@ -2881,12 +2881,12 @@ class OMPCopyprivateClause final
OMPC_copyprivate, SourceLocation(), SourceLocation(),
SourceLocation(), N) {}
- /// \brief Set list of helper expressions, required for proper codegen of the
+ /// Set list of helper expressions, required for proper codegen of the
/// clause. These expressions represent source expression in the final
/// assignment statement performed by the copyprivate clause.
void setSourceExprs(ArrayRef<Expr *> SrcExprs);
- /// \brief Get the list of helper source expressions.
+ /// Get the list of helper source expressions.
MutableArrayRef<Expr *> getSourceExprs() {
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
@@ -2894,12 +2894,12 @@ class OMPCopyprivateClause final
return llvm::makeArrayRef(varlist_end(), varlist_size());
}
- /// \brief Set list of helper expressions, required for proper codegen of the
+ /// Set list of helper expressions, required for proper codegen of the
/// clause. These expressions represent destination expression in the final
/// assignment statement performed by the copyprivate clause.
void setDestinationExprs(ArrayRef<Expr *> DstExprs);
- /// \brief Get the list of helper destination expressions.
+ /// Get the list of helper destination expressions.
MutableArrayRef<Expr *> getDestinationExprs() {
return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
}
@@ -2907,13 +2907,13 @@ class OMPCopyprivateClause final
return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
}
- /// \brief Set list of helper assignment expressions, required for proper
+ /// Set list of helper assignment expressions, required for proper
/// codegen of the clause. These expressions are assignment expressions that
/// assign source helper expressions to destination helper expressions
/// correspondingly.
void setAssignmentOps(ArrayRef<Expr *> AssignmentOps);
- /// \brief Get the list of helper assignment expressions.
+ /// Get the list of helper assignment expressions.
MutableArrayRef<Expr *> getAssignmentOps() {
return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
}
@@ -2922,7 +2922,7 @@ class OMPCopyprivateClause final
}
public:
- /// \brief Creates clause with a list of variables \a VL.
+ /// Creates clause with a list of variables \a VL.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
@@ -2947,7 +2947,7 @@ public:
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps);
- /// \brief Creates an empty clause with \a N variables.
+ /// Creates an empty clause with \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
@@ -2998,7 +2998,7 @@ public:
}
};
-/// \brief This represents implicit clause 'flush' for the '#pragma omp flush'
+/// This represents implicit clause 'flush' for the '#pragma omp flush'
/// directive.
/// This clause does not exist by itself, it can be only as a part of 'omp
/// flush' directive. This clause is introduced to keep the original structure
@@ -3016,7 +3016,7 @@ class OMPFlushClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Build clause with number of variables \a N.
+ /// Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -3027,7 +3027,7 @@ class OMPFlushClause final
: OMPVarListClause<OMPFlushClause>(OMPC_flush, StartLoc, LParenLoc,
EndLoc, N) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPFlushClause(unsigned N)
@@ -3036,7 +3036,7 @@ class OMPFlushClause final
N) {}
public:
- /// \brief Creates clause with a list of variables \a VL.
+ /// Creates clause with a list of variables \a VL.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
@@ -3047,7 +3047,7 @@ public:
SourceLocation LParenLoc, SourceLocation EndLoc,
ArrayRef<Expr *> VL);
- /// \brief Creates an empty clause with \a N variables.
+ /// Creates an empty clause with \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
@@ -3063,7 +3063,7 @@ public:
}
};
-/// \brief This represents implicit clause 'depend' for the '#pragma omp task'
+/// This represents implicit clause 'depend' for the '#pragma omp task'
/// directive.
///
/// \code
@@ -3078,16 +3078,16 @@ class OMPDependClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Dependency type (one of in, out, inout).
+ /// Dependency type (one of in, out, inout).
OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
- /// \brief Dependency type location.
+ /// Dependency type location.
SourceLocation DepLoc;
- /// \brief Colon location.
+ /// Colon location.
SourceLocation ColonLoc;
- /// \brief Build clause with number of variables \a N.
+ /// Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -3098,7 +3098,7 @@ class OMPDependClause final
: OMPVarListClause<OMPDependClause>(OMPC_depend, StartLoc, LParenLoc,
EndLoc, N) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param N Number of variables.
explicit OMPDependClause(unsigned N)
@@ -3106,17 +3106,17 @@ class OMPDependClause final
SourceLocation(), SourceLocation(),
N) {}
- /// \brief Set dependency kind.
+ /// Set dependency kind.
void setDependencyKind(OpenMPDependClauseKind K) { DepKind = K; }
- /// \brief Set dependency kind and its location.
+ /// Set dependency kind and its location.
void setDependencyLoc(SourceLocation Loc) { DepLoc = Loc; }
- /// \brief Set colon location.
+ /// Set colon location.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
public:
- /// \brief Creates clause with a list of variables \a VL.
+ /// Creates clause with a list of variables \a VL.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
@@ -3131,19 +3131,19 @@ public:
SourceLocation EndLoc, OpenMPDependClauseKind DepKind,
SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL);
- /// \brief Creates an empty clause with \a N variables.
+ /// Creates an empty clause with \a N variables.
///
/// \param C AST context.
/// \param N The number of variables.
static OMPDependClause *CreateEmpty(const ASTContext &C, unsigned N);
- /// \brief Get dependency type.
+ /// Get dependency type.
OpenMPDependClauseKind getDependencyKind() const { return DepKind; }
- /// \brief Get dependency type location.
+ /// Get dependency type location.
SourceLocation getDependencyLoc() const { return DepLoc; }
- /// \brief Get colon location.
+ /// Get colon location.
SourceLocation getColonLoc() const { return ColonLoc; }
/// Set the loop counter value for the depend clauses with 'sink|source' kind
@@ -3166,7 +3166,7 @@ public:
}
};
-/// \brief This represents 'device' clause in the '#pragma omp ...'
+/// This represents 'device' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -3177,46 +3177,49 @@ public:
class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Device number.
+ /// Device number.
Stmt *Device = nullptr;
- /// \brief Set the device number.
+ /// Set the device number.
///
/// \param E Device number.
void setDevice(Expr *E) { Device = E; }
public:
- /// \brief Build 'device' clause.
+ /// Build 'device' clause.
///
/// \param E Expression associated with this clause.
+ /// \param CaptureRegion Innermost OpenMP region where expressions in this
+ /// clause must be captured.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- OMPDeviceClause(Expr *E, Stmt *HelperE, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
+ OMPDeviceClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
: OMPClause(OMPC_device, StartLoc, EndLoc), OMPClauseWithPreInit(this),
LParenLoc(LParenLoc), Device(E) {
- setPreInitStmt(HelperE);
+ setPreInitStmt(HelperE, CaptureRegion);
}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPDeviceClause()
: OMPClause(OMPC_device, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return device number.
+ /// Return device number.
Expr *getDevice() { return cast<Expr>(Device); }
- /// \brief Return device number.
+ /// Return device number.
Expr *getDevice() const { return cast<Expr>(Device); }
child_range children() { return child_range(&Device, &Device + 1); }
@@ -3226,7 +3229,7 @@ public:
}
};
-/// \brief This represents 'threads' clause in the '#pragma omp ...' directive.
+/// This represents 'threads' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp ordered threads
@@ -3234,14 +3237,14 @@ public:
/// In this example directive '#pragma omp ordered' has simple 'threads' clause.
class OMPThreadsClause : public OMPClause {
public:
- /// \brief Build 'threads' clause.
+ /// Build 'threads' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_threads, StartLoc, EndLoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPThreadsClause()
: OMPClause(OMPC_threads, SourceLocation(), SourceLocation()) {}
@@ -3254,7 +3257,7 @@ public:
}
};
-/// \brief This represents 'simd' clause in the '#pragma omp ...' directive.
+/// This represents 'simd' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp ordered simd
@@ -3262,14 +3265,14 @@ public:
/// In this example directive '#pragma omp ordered' has simple 'simd' clause.
class OMPSIMDClause : public OMPClause {
public:
- /// \brief Build 'simd' clause.
+ /// Build 'simd' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_simd, StartLoc, EndLoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {}
child_range children() {
@@ -3281,23 +3284,23 @@ public:
}
};
-/// \brief Struct that defines common infrastructure to handle mappable
+/// Struct that defines common infrastructure to handle mappable
/// expressions used in OpenMP clauses.
class OMPClauseMappableExprCommon {
public:
- // \brief Class that represents a component of a mappable expression. E.g.
- // for an expression S.a, the first component is a declaration reference
- // expression associated with 'S' and the second is a member expression
- // associated with the field declaration 'a'. If the expression is an array
- // subscript it may not have any associated declaration. In that case the
- // associated declaration is set to nullptr.
+ /// Class that represents a component of a mappable expression. E.g.
+ /// for an expression S.a, the first component is a declaration reference
+ /// expression associated with 'S' and the second is a member expression
+ /// associated with the field declaration 'a'. If the expression is an array
+ /// subscript it may not have any associated declaration. In that case the
+ /// associated declaration is set to nullptr.
class MappableComponent {
- // \brief Expression associated with the component.
+ /// Expression associated with the component.
Expr *AssociatedExpression = nullptr;
- // \brief Declaration associated with the declaration. If the component does
- // not have a declaration (e.g. array subscripts or section), this is set to
- // nullptr.
+ /// Declaration associated with the declaration. If the component does
+ /// not have a declaration (e.g. array subscripts or section), this is set
+ /// to nullptr.
ValueDecl *AssociatedDeclaration = nullptr;
public:
@@ -3317,29 +3320,29 @@ public:
}
};
- // \brief List of components of an expression. This first one is the whole
+ // List of components of an expression. This first one is the whole
// expression and the last one is the base expression.
using MappableExprComponentList = SmallVector<MappableComponent, 8>;
using MappableExprComponentListRef = ArrayRef<MappableComponent>;
- // \brief List of all component lists associated to the same base declaration.
+ // List of all component lists associated to the same base declaration.
// E.g. if both 'S.a' and 'S.b' are a mappable expressions, each will have
// their component list but the same base declaration 'S'.
using MappableExprComponentLists = SmallVector<MappableExprComponentList, 8>;
using MappableExprComponentListsRef = ArrayRef<MappableExprComponentList>;
protected:
- // \brief Return the total number of elements in a list of component lists.
+ // Return the total number of elements in a list of component lists.
static unsigned
getComponentsTotalNumber(MappableExprComponentListsRef ComponentLists);
- // \brief Return the total number of elements in a list of declarations. All
+ // Return the total number of elements in a list of declarations. All
// declarations are expected to be canonical.
static unsigned
- getUniqueDeclarationsTotalNumber(ArrayRef<ValueDecl *> Declarations);
+ getUniqueDeclarationsTotalNumber(ArrayRef<const ValueDecl *> Declarations);
};
-/// \brief This represents clauses with a list of expressions that are mappable.
+/// This represents clauses with a list of expressions that are mappable.
/// Examples of these clauses are 'map' in
/// '#pragma omp target [enter|exit] [data]...' directives, and 'to' and 'from
/// in '#pragma omp target update...' directives.
@@ -3348,17 +3351,17 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
public OMPClauseMappableExprCommon {
friend class OMPClauseReader;
- /// \brief Number of unique declarations in this clause.
+ /// Number of unique declarations in this clause.
unsigned NumUniqueDeclarations;
- /// \brief Number of component lists in this clause.
+ /// Number of component lists in this clause.
unsigned NumComponentLists;
- /// \brief Total number of components in this clause.
+ /// Total number of components in this clause.
unsigned NumComponents;
protected:
- /// \brief Build a clause for \a NumUniqueDeclarations declarations, \a
+ /// Build a clause for \a NumUniqueDeclarations declarations, \a
/// NumComponentLists total component lists, and \a NumComponents total
/// components.
///
@@ -3380,7 +3383,7 @@ protected:
NumUniqueDeclarations(NumUniqueDeclarations),
NumComponentLists(NumComponentLists), NumComponents(NumComponents) {}
- /// \brief Get the unique declarations that are in the trailing objects of the
+ /// Get the unique declarations that are in the trailing objects of the
/// class.
MutableArrayRef<ValueDecl *> getUniqueDeclsRef() {
return MutableArrayRef<ValueDecl *>(
@@ -3388,7 +3391,7 @@ protected:
NumUniqueDeclarations);
}
- /// \brief Get the unique declarations that are in the trailing objects of the
+ /// Get the unique declarations that are in the trailing objects of the
/// class.
ArrayRef<ValueDecl *> getUniqueDeclsRef() const {
return ArrayRef<ValueDecl *>(
@@ -3397,7 +3400,7 @@ protected:
NumUniqueDeclarations);
}
- /// \brief Set the unique declarations that are in the trailing objects of the
+ /// Set the unique declarations that are in the trailing objects of the
/// class.
void setUniqueDecls(ArrayRef<ValueDecl *> UDs) {
assert(UDs.size() == NumUniqueDeclarations &&
@@ -3405,7 +3408,7 @@ protected:
std::copy(UDs.begin(), UDs.end(), getUniqueDeclsRef().begin());
}
- /// \brief Get the number of lists per declaration that are in the trailing
+ /// Get the number of lists per declaration that are in the trailing
/// objects of the class.
MutableArrayRef<unsigned> getDeclNumListsRef() {
return MutableArrayRef<unsigned>(
@@ -3413,7 +3416,7 @@ protected:
NumUniqueDeclarations);
}
- /// \brief Get the number of lists per declaration that are in the trailing
+ /// Get the number of lists per declaration that are in the trailing
/// objects of the class.
ArrayRef<unsigned> getDeclNumListsRef() const {
return ArrayRef<unsigned>(
@@ -3421,7 +3424,7 @@ protected:
NumUniqueDeclarations);
}
- /// \brief Set the number of lists per declaration that are in the trailing
+ /// Set the number of lists per declaration that are in the trailing
/// objects of the class.
void setDeclNumLists(ArrayRef<unsigned> DNLs) {
assert(DNLs.size() == NumUniqueDeclarations &&
@@ -3429,7 +3432,7 @@ protected:
std::copy(DNLs.begin(), DNLs.end(), getDeclNumListsRef().begin());
}
- /// \brief Get the cumulative component lists sizes that are in the trailing
+ /// Get the cumulative component lists sizes that are in the trailing
/// objects of the class. They are appended after the number of lists.
MutableArrayRef<unsigned> getComponentListSizesRef() {
return MutableArrayRef<unsigned>(
@@ -3438,7 +3441,7 @@ protected:
NumComponentLists);
}
- /// \brief Get the cumulative component lists sizes that are in the trailing
+ /// Get the cumulative component lists sizes that are in the trailing
/// objects of the class. They are appended after the number of lists.
ArrayRef<unsigned> getComponentListSizesRef() const {
return ArrayRef<unsigned>(
@@ -3447,7 +3450,7 @@ protected:
NumComponentLists);
}
- /// \brief Set the cumulative component lists sizes that are in the trailing
+ /// Set the cumulative component lists sizes that are in the trailing
/// objects of the class.
void setComponentListSizes(ArrayRef<unsigned> CLSs) {
assert(CLSs.size() == NumComponentLists &&
@@ -3455,7 +3458,7 @@ protected:
std::copy(CLSs.begin(), CLSs.end(), getComponentListSizesRef().begin());
}
- /// \brief Get the components that are in the trailing objects of the class.
+ /// Get the components that are in the trailing objects of the class.
MutableArrayRef<MappableComponent> getComponentsRef() {
return MutableArrayRef<MappableComponent>(
static_cast<T *>(this)
@@ -3463,7 +3466,7 @@ protected:
NumComponents);
}
- /// \brief Get the components that are in the trailing objects of the class.
+ /// Get the components that are in the trailing objects of the class.
ArrayRef<MappableComponent> getComponentsRef() const {
return ArrayRef<MappableComponent>(
static_cast<const T *>(this)
@@ -3471,7 +3474,7 @@ protected:
NumComponents);
}
- /// \brief Set the components that are in the trailing objects of the class.
+ /// Set the components that are in the trailing objects of the class.
/// This requires the list sizes so that it can also fill the original
/// expressions, which are the first component of each list.
void setComponents(ArrayRef<MappableComponent> Components,
@@ -3483,7 +3486,7 @@ protected:
std::copy(Components.begin(), Components.end(), getComponentsRef().begin());
}
- /// \brief Fill the clause information from the list of declarations and
+ /// Fill the clause information from the list of declarations and
/// associated component lists.
void setClauseInfo(ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists) {
@@ -3560,17 +3563,17 @@ protected:
}
public:
- /// \brief Return the number of unique base declarations in this clause.
+ /// Return the number of unique base declarations in this clause.
unsigned getUniqueDeclarationsNum() const { return NumUniqueDeclarations; }
- /// \brief Return the number of lists derived from the clause expressions.
+ /// Return the number of lists derived from the clause expressions.
unsigned getTotalComponentListNum() const { return NumComponentLists; }
- /// \brief Return the total number of components in all lists derived from the
+ /// Return the total number of components in all lists derived from the
/// clause.
unsigned getTotalComponentsNum() const { return NumComponents; }
- /// \brief Iterator that browse the components by lists. It also allows
+ /// Iterator that browse the components by lists. It also allows
/// browsing components of a single declaration.
class const_component_lists_iterator
: public llvm::iterator_adaptor_base<
@@ -3600,7 +3603,7 @@ public:
MappableExprComponentListRef::const_iterator End;
public:
- /// \brief Construct an iterator that scans all lists.
+ /// Construct an iterator that scans all lists.
explicit const_component_lists_iterator(
ArrayRef<ValueDecl *> UniqueDecls, ArrayRef<unsigned> DeclsListNum,
ArrayRef<unsigned> CumulativeListSizes,
@@ -3616,7 +3619,7 @@ public:
RemainingLists = *NumListsCur;
}
- /// \brief Construct an iterator that scan lists for a given declaration \a
+ /// Construct an iterator that scan lists for a given declaration \a
/// Declaration.
explicit const_component_lists_iterator(
const ValueDecl *Declaration, ArrayRef<ValueDecl *> UniqueDecls,
@@ -3706,7 +3709,7 @@ public:
using const_component_lists_range =
llvm::iterator_range<const_component_lists_iterator>;
- /// \brief Iterators for all component lists.
+ /// Iterators for all component lists.
const_component_lists_iterator component_lists_begin() const {
return const_component_lists_iterator(
getUniqueDeclsRef(), getDeclNumListsRef(), getComponentListSizesRef(),
@@ -3722,7 +3725,7 @@ public:
return {component_lists_begin(), component_lists_end()};
}
- /// \brief Iterators for component lists associated with the provided
+ /// Iterators for component lists associated with the provided
/// declaration.
const_component_lists_iterator
decl_component_lists_begin(const ValueDecl *VD) const {
@@ -3775,7 +3778,7 @@ public:
}
};
-/// \brief This represents clause 'map' in the '#pragma omp ...'
+/// This represents clause 'map' in the '#pragma omp ...'
/// directives.
///
/// \code
@@ -3804,22 +3807,22 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
return getUniqueDeclarationsNum() + getTotalComponentListNum();
}
- /// \brief Map type modifier for the 'map' clause.
+ /// Map type modifier for the 'map' clause.
OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;
- /// \brief Map type for the 'map' clause.
+ /// Map type for the 'map' clause.
OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
- /// \brief Is this an implicit map type or not.
+ /// Is this an implicit map type or not.
bool MapTypeIsImplicit = false;
- /// \brief Location of the map type.
+ /// Location of the map type.
SourceLocation MapLoc;
- /// \brief Colon location.
+ /// Colon location.
SourceLocation ColonLoc;
- /// \brief Build a clause for \a NumVars listed expressions, \a
+ /// Build a clause for \a NumVars listed expressions, \a
/// NumUniqueDeclarations declarations, \a NumComponentLists total component
/// lists, and \a NumComponents total expression components.
///
@@ -3846,7 +3849,7 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
MapTypeModifier(MapTypeModifier), MapType(MapType),
MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param NumVars Number of expressions listed in this clause.
/// \param NumUniqueDeclarations Number of unique base declarations in this
@@ -3859,26 +3862,26 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(),
NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {}
- /// \brief Set type modifier for the clause.
+ /// Set type modifier for the clause.
///
/// \param T Type Modifier for the clause.
void setMapTypeModifier(OpenMPMapClauseKind T) { MapTypeModifier = T; }
- /// \brief Set type for the clause.
+ /// Set type for the clause.
///
/// \param T Type for the clause.
void setMapType(OpenMPMapClauseKind T) { MapType = T; }
- /// \brief Set type location.
+ /// Set type location.
///
/// \param TLoc Type location.
void setMapLoc(SourceLocation TLoc) { MapLoc = TLoc; }
- /// \brief Set colon location.
+ /// Set colon location.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
public:
- /// \brief Creates clause with a list of variables \a VL.
+ /// Creates clause with a list of variables \a VL.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
@@ -3899,7 +3902,7 @@ public:
OpenMPMapClauseKind Type, bool TypeIsImplicit,
SourceLocation TypeLoc);
- /// \brief Creates an empty clause with the place for for \a NumVars original
+ /// Creates an empty clause with the place for \a NumVars original
/// expressions, \a NumUniqueDeclarations declarations, \NumComponentLists
/// lists, and \a NumComponents expression components.
///
@@ -3915,25 +3918,25 @@ public:
unsigned NumComponentLists,
unsigned NumComponents);
- /// \brief Fetches mapping kind for the clause.
+ /// Fetches mapping kind for the clause.
OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; }
- /// \brief Is this an implicit map type?
+ /// Is this an implicit map type?
/// We have to capture 'IsMapTypeImplicit' from the parser for more
/// informative error messages. It helps distinguish map(r) from
/// map(tofrom: r), which is important to print more helpful error
/// messages for some target directives.
bool isImplicitMapType() const LLVM_READONLY { return MapTypeIsImplicit; }
- /// \brief Fetches the map type modifier for the clause.
+ /// Fetches the map type modifier for the clause.
OpenMPMapClauseKind getMapTypeModifier() const LLVM_READONLY {
return MapTypeModifier;
}
- /// \brief Fetches location of clause mapping kind.
+ /// Fetches location of clause mapping kind.
SourceLocation getMapLoc() const LLVM_READONLY { return MapLoc; }
- /// \brief Get colon location.
+ /// Get colon location.
SourceLocation getColonLoc() const { return ColonLoc; }
child_range children() {
@@ -3947,7 +3950,7 @@ public:
}
};
-/// \brief This represents 'num_teams' clause in the '#pragma omp ...'
+/// This represents 'num_teams' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -3958,19 +3961,19 @@ public:
class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief NumTeams number.
+ /// NumTeams number.
Stmt *NumTeams = nullptr;
- /// \brief Set the NumTeams number.
+ /// Set the NumTeams number.
///
/// \param E NumTeams number.
void setNumTeams(Expr *E) { NumTeams = E; }
public:
- /// \brief Build 'num_teams' clause.
+ /// Build 'num_teams' clause.
///
/// \param E Expression associated with this clause.
/// \param HelperE Helper Expression associated with this clause.
@@ -3987,21 +3990,21 @@ public:
setPreInitStmt(HelperE, CaptureRegion);
}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPNumTeamsClause()
: OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return NumTeams number.
+ /// Return NumTeams number.
Expr *getNumTeams() { return cast<Expr>(NumTeams); }
- /// \brief Return NumTeams number.
+ /// Return NumTeams number.
Expr *getNumTeams() const { return cast<Expr>(NumTeams); }
child_range children() { return child_range(&NumTeams, &NumTeams + 1); }
@@ -4011,7 +4014,7 @@ public:
}
};
-/// \brief This represents 'thread_limit' clause in the '#pragma omp ...'
+/// This represents 'thread_limit' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -4022,19 +4025,19 @@ public:
class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief ThreadLimit number.
+ /// ThreadLimit number.
Stmt *ThreadLimit = nullptr;
- /// \brief Set the ThreadLimit number.
+ /// Set the ThreadLimit number.
///
/// \param E ThreadLimit number.
void setThreadLimit(Expr *E) { ThreadLimit = E; }
public:
- /// \brief Build 'thread_limit' clause.
+ /// Build 'thread_limit' clause.
///
/// \param E Expression associated with this clause.
/// \param HelperE Helper Expression associated with this clause.
@@ -4052,21 +4055,21 @@ public:
setPreInitStmt(HelperE, CaptureRegion);
}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPThreadLimitClause()
: OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return ThreadLimit number.
+ /// Return ThreadLimit number.
Expr *getThreadLimit() { return cast<Expr>(ThreadLimit); }
- /// \brief Return ThreadLimit number.
+ /// Return ThreadLimit number.
Expr *getThreadLimit() const { return cast<Expr>(ThreadLimit); }
child_range children() { return child_range(&ThreadLimit, &ThreadLimit + 1); }
@@ -4076,7 +4079,7 @@ public:
}
};
-/// \brief This represents 'priority' clause in the '#pragma omp ...'
+/// This represents 'priority' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -4087,19 +4090,19 @@ public:
class OMPPriorityClause : public OMPClause {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Priority number.
+ /// Priority number.
Stmt *Priority = nullptr;
- /// \brief Set the Priority number.
+ /// Set the Priority number.
///
/// \param E Priority number.
void setPriority(Expr *E) { Priority = E; }
public:
- /// \brief Build 'priority' clause.
+ /// Build 'priority' clause.
///
/// \param E Expression associated with this clause.
/// \param StartLoc Starting location of the clause.
@@ -4110,20 +4113,20 @@ public:
: OMPClause(OMPC_priority, StartLoc, EndLoc), LParenLoc(LParenLoc),
Priority(E) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPPriorityClause()
: OMPClause(OMPC_priority, SourceLocation(), SourceLocation()) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return Priority number.
+ /// Return Priority number.
Expr *getPriority() { return cast<Expr>(Priority); }
- /// \brief Return Priority number.
+ /// Return Priority number.
Expr *getPriority() const { return cast<Expr>(Priority); }
child_range children() { return child_range(&Priority, &Priority + 1); }
@@ -4133,7 +4136,7 @@ public:
}
};
-/// \brief This represents 'grainsize' clause in the '#pragma omp ...'
+/// This represents 'grainsize' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -4144,17 +4147,17 @@ public:
class OMPGrainsizeClause : public OMPClause {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Safe iteration space distance.
+ /// Safe iteration space distance.
Stmt *Grainsize = nullptr;
- /// \brief Set safelen.
+ /// Set safelen.
void setGrainsize(Expr *Size) { Grainsize = Size; }
public:
- /// \brief Build 'grainsize' clause.
+ /// Build 'grainsize' clause.
///
/// \param Size Expression associated with this clause.
/// \param StartLoc Starting location of the clause.
@@ -4164,17 +4167,17 @@ public:
: OMPClause(OMPC_grainsize, StartLoc, EndLoc), LParenLoc(LParenLoc),
Grainsize(Size) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
explicit OMPGrainsizeClause()
: OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return safe iteration space distance.
+ /// Return safe iteration space distance.
Expr *getGrainsize() const { return cast_or_null<Expr>(Grainsize); }
child_range children() { return child_range(&Grainsize, &Grainsize + 1); }
@@ -4184,7 +4187,7 @@ public:
}
};
-/// \brief This represents 'nogroup' clause in the '#pragma omp ...' directive.
+/// This represents 'nogroup' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp taskloop nogroup
@@ -4192,14 +4195,14 @@ public:
/// In this example directive '#pragma omp taskloop' has 'nogroup' clause.
class OMPNogroupClause : public OMPClause {
public:
- /// \brief Build 'nogroup' clause.
+ /// Build 'nogroup' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPClause(OMPC_nogroup, StartLoc, EndLoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPNogroupClause()
: OMPClause(OMPC_nogroup, SourceLocation(), SourceLocation()) {}
@@ -4212,7 +4215,7 @@ public:
}
};
-/// \brief This represents 'num_tasks' clause in the '#pragma omp ...'
+/// This represents 'num_tasks' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -4223,17 +4226,17 @@ public:
class OMPNumTasksClause : public OMPClause {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Safe iteration space distance.
+ /// Safe iteration space distance.
Stmt *NumTasks = nullptr;
- /// \brief Set safelen.
+ /// Set safelen.
void setNumTasks(Expr *Size) { NumTasks = Size; }
public:
- /// \brief Build 'num_tasks' clause.
+ /// Build 'num_tasks' clause.
///
/// \param Size Expression associated with this clause.
/// \param StartLoc Starting location of the clause.
@@ -4243,17 +4246,17 @@ public:
: OMPClause(OMPC_num_tasks, StartLoc, EndLoc), LParenLoc(LParenLoc),
NumTasks(Size) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
explicit OMPNumTasksClause()
: OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return safe iteration space distance.
+ /// Return safe iteration space distance.
Expr *getNumTasks() const { return cast_or_null<Expr>(NumTasks); }
child_range children() { return child_range(&NumTasks, &NumTasks + 1); }
@@ -4263,7 +4266,7 @@ public:
}
};
-/// \brief This represents 'hint' clause in the '#pragma omp ...' directive.
+/// This represents 'hint' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp critical (name) hint(6)
@@ -4273,17 +4276,17 @@ public:
class OMPHintClause : public OMPClause {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Hint expression of the 'hint' clause.
+ /// Hint expression of the 'hint' clause.
Stmt *Hint = nullptr;
- /// \brief Set hint expression.
+ /// Set hint expression.
void setHint(Expr *H) { Hint = H; }
public:
- /// \brief Build 'hint' clause with expression \a Hint.
+ /// Build 'hint' clause with expression \a Hint.
///
/// \param Hint Hint expression.
/// \param StartLoc Starting location of the clause.
@@ -4294,16 +4297,16 @@ public:
: OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc),
Hint(Hint) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
OMPHintClause() : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()) {}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
+ /// Returns the location of '('.
SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Returns number of threads.
+ /// Returns number of threads.
Expr *getHint() const { return cast_or_null<Expr>(Hint); }
child_range children() { return child_range(&Hint, &Hint + 1); }
@@ -4313,7 +4316,7 @@ public:
}
};
-/// \brief This represents 'dist_schedule' clause in the '#pragma omp ...'
+/// This represents 'dist_schedule' clause in the '#pragma omp ...'
/// directive.
///
/// \code
@@ -4324,48 +4327,48 @@ public:
class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief A kind of the 'schedule' clause.
+ /// A kind of the 'schedule' clause.
OpenMPDistScheduleClauseKind Kind = OMPC_DIST_SCHEDULE_unknown;
- /// \brief Start location of the schedule kind in source code.
+ /// Start location of the schedule kind in source code.
SourceLocation KindLoc;
- /// \brief Location of ',' (if any).
+ /// Location of ',' (if any).
SourceLocation CommaLoc;
- /// \brief Chunk size.
+ /// Chunk size.
Expr *ChunkSize = nullptr;
- /// \brief Set schedule kind.
+ /// Set schedule kind.
///
/// \param K Schedule kind.
void setDistScheduleKind(OpenMPDistScheduleClauseKind K) { Kind = K; }
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
///
/// \param Loc Location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Set schedule kind start location.
+ /// Set schedule kind start location.
///
/// \param KLoc Schedule kind location.
void setDistScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
- /// \brief Set location of ','.
+ /// Set location of ','.
///
/// \param Loc Location of ','.
void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; }
- /// \brief Set chunk size.
+ /// Set chunk size.
///
/// \param E Chunk size.
void setChunkSize(Expr *E) { ChunkSize = E; }
public:
- /// \brief Build 'dist_schedule' clause with schedule kind \a Kind and chunk
+ /// Build 'dist_schedule' clause with schedule kind \a Kind and chunk
/// size expression \a ChunkSize.
///
/// \param StartLoc Starting location of the clause.
@@ -4387,27 +4390,27 @@ public:
setPreInitStmt(HelperChunkSize);
}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
explicit OMPDistScheduleClause()
: OMPClause(OMPC_dist_schedule, SourceLocation(), SourceLocation()),
OMPClauseWithPreInit(this) {}
- /// \brief Get kind of the clause.
+ /// Get kind of the clause.
OpenMPDistScheduleClauseKind getDistScheduleKind() const { return Kind; }
- /// \brief Get location of '('.
+ /// Get location of '('.
SourceLocation getLParenLoc() { return LParenLoc; }
- /// \brief Get kind location.
+ /// Get kind location.
SourceLocation getDistScheduleKindLoc() { return KindLoc; }
- /// \brief Get location of ','.
+ /// Get location of ','.
SourceLocation getCommaLoc() { return CommaLoc; }
- /// \brief Get chunk size.
+ /// Get chunk size.
Expr *getChunkSize() { return ChunkSize; }
- /// \brief Get chunk size.
+ /// Get chunk size.
const Expr *getChunkSize() const { return ChunkSize; }
child_range children() {
@@ -4420,7 +4423,7 @@ public:
}
};
-/// \brief This represents 'defaultmap' clause in the '#pragma omp ...' directive.
+/// This represents 'defaultmap' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp target defaultmap(tofrom: scalar)
@@ -4430,50 +4433,50 @@ public:
class OMPDefaultmapClause : public OMPClause {
friend class OMPClauseReader;
- /// \brief Location of '('.
+ /// Location of '('.
SourceLocation LParenLoc;
- /// \brief Modifiers for 'defaultmap' clause.
+ /// Modifiers for 'defaultmap' clause.
OpenMPDefaultmapClauseModifier Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;
- /// \brief Locations of modifiers.
+ /// Locations of modifiers.
SourceLocation ModifierLoc;
- /// \brief A kind of the 'defaultmap' clause.
+ /// A kind of the 'defaultmap' clause.
OpenMPDefaultmapClauseKind Kind = OMPC_DEFAULTMAP_unknown;
- /// \brief Start location of the defaultmap kind in source code.
+ /// Start location of the defaultmap kind in source code.
SourceLocation KindLoc;
- /// \brief Set defaultmap kind.
+ /// Set defaultmap kind.
///
/// \param K Defaultmap kind.
void setDefaultmapKind(OpenMPDefaultmapClauseKind K) { Kind = K; }
- /// \brief Set the defaultmap modifier.
+ /// Set the defaultmap modifier.
///
/// \param M Defaultmap modifier.
void setDefaultmapModifier(OpenMPDefaultmapClauseModifier M) {
Modifier = M;
}
- /// \brief Set location of the defaultmap modifier.
+ /// Set location of the defaultmap modifier.
void setDefaultmapModifierLoc(SourceLocation Loc) {
ModifierLoc = Loc;
}
- /// \brief Sets the location of '('.
+ /// Sets the location of '('.
///
/// \param Loc Location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Set defaultmap kind start location.
+ /// Set defaultmap kind start location.
///
/// \param KLoc Defaultmap kind location.
void setDefaultmapKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
public:
- /// \brief Build 'defaultmap' clause with defaultmap kind \a Kind
+ /// Build 'defaultmap' clause with defaultmap kind \a Kind
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
@@ -4489,25 +4492,25 @@ public:
: OMPClause(OMPC_defaultmap, StartLoc, EndLoc), LParenLoc(LParenLoc),
Modifier(M), ModifierLoc(MLoc), Kind(Kind), KindLoc(KLoc) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
explicit OMPDefaultmapClause()
: OMPClause(OMPC_defaultmap, SourceLocation(), SourceLocation()) {}
- /// \brief Get kind of the clause.
+ /// Get kind of the clause.
OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; }
- /// \brief Get the modifier of the clause.
+ /// Get the modifier of the clause.
OpenMPDefaultmapClauseModifier getDefaultmapModifier() const {
return Modifier;
}
- /// \brief Get location of '('.
+ /// Get location of '('.
SourceLocation getLParenLoc() { return LParenLoc; }
- /// \brief Get kind location.
+ /// Get kind location.
SourceLocation getDefaultmapKindLoc() { return KindLoc; }
- /// \brief Get the modifier location.
+ /// Get the modifier location.
SourceLocation getDefaultmapModifierLoc() const {
return ModifierLoc;
}
@@ -4521,7 +4524,7 @@ public:
}
};
-/// \brief This represents clause 'to' in the '#pragma omp ...'
+/// This represents clause 'to' in the '#pragma omp ...'
/// directives.
///
/// \code
@@ -4538,7 +4541,7 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Build clause with number of variables \a NumVars.
+ /// Build clause with number of variables \a NumVars.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
@@ -4555,7 +4558,7 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
NumUniqueDeclarations, NumComponentLists,
NumComponents) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param NumVars Number of expressions listed in this clause.
/// \param NumUniqueDeclarations Number of unique base declarations in this
@@ -4581,7 +4584,7 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
}
public:
- /// \brief Creates clause with a list of variables \a Vars.
+ /// Creates clause with a list of variables \a Vars.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
@@ -4595,7 +4598,7 @@ public:
ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists);
- /// \brief Creates an empty clause with the place for \a NumVars variables.
+ /// Creates an empty clause with the place for \a NumVars variables.
///
/// \param C AST context.
/// \param NumVars Number of expressions listed in the clause.
@@ -4619,7 +4622,7 @@ public:
}
};
-/// \brief This represents clause 'from' in the '#pragma omp ...'
+/// This represents clause 'from' in the '#pragma omp ...'
/// directives.
///
/// \code
@@ -4637,7 +4640,7 @@ class OMPFromClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// \brief Build clause with number of variables \a NumVars.
+ /// Build clause with number of variables \a NumVars.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
@@ -4654,7 +4657,7 @@ class OMPFromClause final
NumVars, NumUniqueDeclarations,
NumComponentLists, NumComponents) {}
- /// \brief Build an empty clause.
+ /// Build an empty clause.
///
/// \param NumVars Number of expressions listed in this clause.
/// \param NumUniqueDeclarations Number of unique base declarations in this
@@ -4680,7 +4683,7 @@ class OMPFromClause final
}
public:
- /// \brief Creates clause with a list of variables \a Vars.
+ /// Creates clause with a list of variables \a Vars.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
@@ -4694,7 +4697,7 @@ public:
ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists);
- /// \brief Creates an empty clause with the place for \a NumVars variables.
+ /// Creates an empty clause with the place for \a NumVars variables.
///
/// \param C AST context.
/// \param NumVars Number of expressions listed in the clause.
diff --git a/include/clang/AST/OperationKinds.def b/include/clang/AST/OperationKinds.def
index b13cf3b63276f..823e32424f1ee 100644
--- a/include/clang/AST/OperationKinds.def
+++ b/include/clang/AST/OperationKinds.def
@@ -227,87 +227,87 @@ CAST_OPERATION(BlockPointerToObjCPointerCast)
/// to a block pointer. Block-to-block casts are bitcasts.
CAST_OPERATION(AnyPointerToBlockPointerCast)
-/// \brief Converting between two Objective-C object types, which
+/// Converting between two Objective-C object types, which
/// can occur when performing reference binding to an Objective-C
/// object.
CAST_OPERATION(ObjCObjectLValueCast)
-/// \brief A conversion of a floating point real to a floating point
+/// A conversion of a floating point real to a floating point
/// complex of the original type. Injects the value as the real
/// component with a zero imaginary component.
/// float -> _Complex float
CAST_OPERATION(FloatingRealToComplex)
-/// \brief Converts a floating point complex to floating point real
+/// Converts a floating point complex to floating point real
/// of the source's element type. Just discards the imaginary
/// component.
/// _Complex long double -> long double
CAST_OPERATION(FloatingComplexToReal)
-/// \brief Converts a floating point complex to bool by comparing
+/// Converts a floating point complex to bool by comparing
/// against 0+0i.
CAST_OPERATION(FloatingComplexToBoolean)
-/// \brief Converts between different floating point complex types.
+/// Converts between different floating point complex types.
/// _Complex float -> _Complex double
CAST_OPERATION(FloatingComplexCast)
-/// \brief Converts from a floating complex to an integral complex.
+/// Converts from a floating complex to an integral complex.
/// _Complex float -> _Complex int
CAST_OPERATION(FloatingComplexToIntegralComplex)
-/// \brief Converts from an integral real to an integral complex
+/// Converts from an integral real to an integral complex
/// whose element type matches the source. Injects the value as
/// the real component with a zero imaginary component.
/// long -> _Complex long
CAST_OPERATION(IntegralRealToComplex)
-/// \brief Converts an integral complex to an integral real of the
+/// Converts an integral complex to an integral real of the
/// source's element type by discarding the imaginary component.
/// _Complex short -> short
CAST_OPERATION(IntegralComplexToReal)
-/// \brief Converts an integral complex to bool by comparing against
+/// Converts an integral complex to bool by comparing against
/// 0+0i.
CAST_OPERATION(IntegralComplexToBoolean)
-/// \brief Converts between different integral complex types.
+/// Converts between different integral complex types.
/// _Complex char -> _Complex long long
/// _Complex unsigned int -> _Complex signed int
CAST_OPERATION(IntegralComplexCast)
-/// \brief Converts from an integral complex to a floating complex.
+/// Converts from an integral complex to a floating complex.
/// _Complex unsigned -> _Complex float
CAST_OPERATION(IntegralComplexToFloatingComplex)
-/// \brief [ARC] Produces a retainable object pointer so that it may
+/// [ARC] Produces a retainable object pointer so that it may
/// be consumed, e.g. by being passed to a consuming parameter.
/// Calls objc_retain.
CAST_OPERATION(ARCProduceObject)
-/// \brief [ARC] Consumes a retainable object pointer that has just
+/// [ARC] Consumes a retainable object pointer that has just
/// been produced, e.g. as the return value of a retaining call.
/// Enters a cleanup to call objc_release at some indefinite time.
CAST_OPERATION(ARCConsumeObject)
-/// \brief [ARC] Reclaim a retainable object pointer object that may
+/// [ARC] Reclaim a retainable object pointer object that may
/// have been produced and autoreleased as part of a function return
/// sequence.
CAST_OPERATION(ARCReclaimReturnedObject)
-/// \brief [ARC] Causes a value of block type to be copied to the
+/// [ARC] Causes a value of block type to be copied to the
/// heap, if it is not already there. A number of other operations
/// in ARC cause blocks to be copied; this is for cases where that
/// would not otherwise be guaranteed, such as when casting to a
/// non-block pointer type.
CAST_OPERATION(ARCExtendBlockObject)
-/// \brief Converts from _Atomic(T) to T.
+/// Converts from _Atomic(T) to T.
CAST_OPERATION(AtomicToNonAtomic)
-/// \brief Converts from T to _Atomic(T).
+/// Converts from T to _Atomic(T).
CAST_OPERATION(NonAtomicToAtomic)
-/// \brief Causes a block literal to by copied to the heap and then
+/// Causes a block literal to by copied to the heap and then
/// autoreleased.
///
/// This particular cast kind is used for the conversion from a C++11
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
index e3832689d64b8..c7e01fa1834e8 100644
--- a/include/clang/AST/OperationKinds.h
+++ b/include/clang/AST/OperationKinds.h
@@ -33,15 +33,15 @@ enum UnaryOperatorKind {
#include "clang/AST/OperationKinds.def"
};
-/// \brief The kind of bridging performed by the Objective-C bridge cast.
+/// The kind of bridging performed by the Objective-C bridge cast.
enum ObjCBridgeCastKind {
- /// \brief Bridging via __bridge, which does nothing but reinterpret
+ /// Bridging via __bridge, which does nothing but reinterpret
/// the bits.
OBC_Bridge,
- /// \brief Bridging via __bridge_transfer, which transfers ownership of an
+ /// Bridging via __bridge_transfer, which transfers ownership of an
/// Objective-C pointer into ARC.
OBC_BridgeTransfer,
- /// \brief Bridging via __bridge_retain, which makes an ARC object available
+ /// Bridging via __bridge_retain, which makes an ARC object available
/// as a +1 C pointer.
OBC_BridgeRetained
};
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
index 8945c413d2685..c1c76ceaaf692 100644
--- a/include/clang/AST/ParentMap.h
+++ b/include/clang/AST/ParentMap.h
@@ -24,7 +24,7 @@ public:
ParentMap(Stmt* ASTRoot);
~ParentMap();
- /// \brief Adds and/or updates the parent/child-relations of the complete
+ /// Adds and/or updates the parent/child-relations of the complete
/// stmt tree of S. All children of S including indirect descendants are
/// visited and updated or inserted but not the parents of S.
void addStmt(Stmt* S);
diff --git a/include/clang/Sema/PrettyDeclStackTrace.h b/include/clang/AST/PrettyDeclStackTrace.h
index ca22e640deb49..8eb519eae26da 100644
--- a/include/clang/Sema/PrettyDeclStackTrace.h
+++ b/include/clang/AST/PrettyDeclStackTrace.h
@@ -13,31 +13,31 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_PRETTYDECLSTACKTRACE_H
-#define LLVM_CLANG_SEMA_PRETTYDECLSTACKTRACE_H
+#ifndef LLVM_CLANG_AST_PRETTYDECLSTACKTRACE_H
+#define LLVM_CLANG_AST_PRETTYDECLSTACKTRACE_H
#include "clang/Basic/SourceLocation.h"
#include "llvm/Support/PrettyStackTrace.h"
namespace clang {
+class ASTContext;
class Decl;
-class Sema;
class SourceManager;
/// PrettyDeclStackTraceEntry - If a crash occurs in the parser while
/// parsing something related to a declaration, include that
/// declaration in the stack trace.
class PrettyDeclStackTraceEntry : public llvm::PrettyStackTraceEntry {
- Sema &S;
+ ASTContext &Context;
Decl *TheDecl;
SourceLocation Loc;
const char *Message;
public:
- PrettyDeclStackTraceEntry(Sema &S, Decl *D, SourceLocation Loc,
+ PrettyDeclStackTraceEntry(ASTContext &Ctx, Decl *D, SourceLocation Loc,
const char *Msg)
- : S(S), TheDecl(D), Loc(Loc), Message(Msg) {}
+ : Context(Ctx), TheDecl(D), Loc(Loc), Message(Msg) {}
void print(raw_ostream &OS) const override;
};
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index e831b903cbae6..41c804486c358 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -36,7 +36,7 @@ public:
/// This type is intended to be small and suitable for passing by value.
/// It is very frequently copied.
struct PrintingPolicy {
- /// \brief Create a default printing policy for the specified language.
+ /// Create a default printing policy for the specified language.
PrintingPolicy(const LangOptions &LO)
: Indentation(2), SuppressSpecifiers(false),
SuppressTagKeyword(LO.CPlusPlus),
diff --git a/include/clang/AST/QualTypeNames.h b/include/clang/AST/QualTypeNames.h
index 86d805feeed76..422ed9e4c8fc4 100644
--- a/include/clang/AST/QualTypeNames.h
+++ b/include/clang/AST/QualTypeNames.h
@@ -63,7 +63,7 @@
namespace clang {
namespace TypeName {
-/// \brief Get the fully qualified name for a type. This includes full
+/// Get the fully qualified name for a type. This includes full
/// qualification of all template parameters etc.
///
/// \param[in] QT - the type for which the fully qualified name will be
@@ -72,9 +72,10 @@ namespace TypeName {
/// \param[in] WithGlobalNsPrefix - If true, then the global namespace
/// specifier "::" will be prepended to the fully qualified name.
std::string getFullyQualifiedName(QualType QT, const ASTContext &Ctx,
+ const PrintingPolicy &Policy,
bool WithGlobalNsPrefix = false);
-/// \brief Generates a QualType that can be used to name the same type
+/// Generates a QualType that can be used to name the same type
/// if used at the end of the current translation unit. This ignores
/// issues such as type shadowing.
///
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index 2e005ddbd027d..8327efc750fd3 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -41,7 +41,7 @@ public:
RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { }
RawComment(const SourceManager &SourceMgr, SourceRange SR,
- bool Merged, bool ParseAllComments);
+ const CommentOptions &CommentOpts, bool Merged);
CommentKind getKind() const LLVM_READONLY {
return (CommentKind) Kind;
@@ -70,7 +70,6 @@ public:
/// \code /**< stuff */ \endcode
/// \code /*!< stuff */ \endcode
bool isTrailingComment() const LLVM_READONLY {
- assert(isDocumentation());
return IsTrailingComment;
}
@@ -83,8 +82,7 @@ public:
/// Returns true if this comment is not a documentation comment.
bool isOrdinary() const LLVM_READONLY {
- return ((Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC)) &&
- !ParseAllComments;
+ return ((Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC));
}
/// Returns true if this comment any kind of a documentation comment.
@@ -92,11 +90,6 @@ public:
return !isInvalid() && !isOrdinary();
}
- /// Returns whether we are parsing all comments.
- bool isParseAllComments() const LLVM_READONLY {
- return ParseAllComments;
- }
-
/// Returns raw comment text with comment markers.
StringRef getRawText(const SourceManager &SourceMgr) const {
if (RawTextValid)
@@ -118,6 +111,30 @@ public:
return extractBriefText(Context);
}
+ /// Returns sanitized comment text, suitable for presentation in editor UIs.
+ /// E.g. will transform:
+ /// // This is a long multiline comment.
+ /// // Parts of it might be indented.
+ /// /* The comments styles might be mixed. */
+ /// into
+ /// "This is a long multiline comment.\n"
+ /// " Parts of it might be indented.\n"
+ /// "The comments styles might be mixed."
+ /// Also removes leading indentation and sanitizes some common cases:
+ /// /* This is a first line.
+ /// * This is a second line. It is indented.
+ /// * This is a third line. */
+ /// and
+ /// /* This is a first line.
+ /// This is a second line. It is indented.
+ /// This is a third line. */
+ /// will both turn into:
+ /// "This is a first line.\n"
+ /// " This is a second line. It is indented.\n"
+ /// "This is a third line."
+ std::string getFormattedText(const SourceManager &SourceMgr,
+ DiagnosticsEngine &Diags) const;
+
/// Parse the comment, assuming it is attached to decl \c D.
comments::FullComment *parse(const ASTContext &Context,
const Preprocessor *PP, const Decl *D) const;
@@ -139,18 +156,12 @@ private:
bool IsTrailingComment : 1;
bool IsAlmostTrailingComment : 1;
- /// When true, ordinary comments starting with "//" and "/*" will be
- /// considered as documentation comments.
- bool ParseAllComments : 1;
-
- /// \brief Constructor for AST deserialization.
+ /// Constructor for AST deserialization.
RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment,
- bool IsAlmostTrailingComment,
- bool ParseAllComments) :
+ bool IsAlmostTrailingComment) :
Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K),
IsAttached(false), IsTrailingComment(IsTrailingComment),
- IsAlmostTrailingComment(IsAlmostTrailingComment),
- ParseAllComments(ParseAllComments)
+ IsAlmostTrailingComment(IsAlmostTrailingComment)
{ }
StringRef getRawTextSlow(const SourceManager &SourceMgr) const;
@@ -160,7 +171,7 @@ private:
friend class ASTReader;
};
-/// \brief Compare comments' source locations.
+/// Compare comments' source locations.
template<>
class BeforeThanCompare<RawComment> {
const SourceManager &SM;
@@ -177,13 +188,14 @@ public:
}
};
-/// \brief This class represents all comments included in the translation unit,
+/// This class represents all comments included in the translation unit,
/// sorted in order of appearance in the translation unit.
class RawCommentList {
public:
RawCommentList(SourceManager &SourceMgr) : SourceMgr(SourceMgr) {}
- void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator);
+ void addComment(const RawComment &RC, const CommentOptions &CommentOpts,
+ llvm::BumpPtrAllocator &Allocator);
ArrayRef<RawComment *> getComments() const {
return Comments;
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 696d44efa0d9d..dc60ef892b073 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -111,7 +111,7 @@ private:
/// Only used for MS-ABI.
bool EndsWithZeroSizedObject : 1;
- /// \brief True if this class is zero sized or first base is zero sized or
+ /// 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;
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index ba76ea0a0df55..0d2b670507c12 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -83,7 +83,7 @@ namespace clang {
return false; \
} while (false)
-/// \brief A class that does preorder or postorder
+/// A class that does preorder or postorder
/// depth-first traversal on the entire Clang AST and visits each node.
///
/// This class performs three distinct tasks:
@@ -146,7 +146,7 @@ namespace clang {
/// from which they were produced.
///
/// By default, this visitor preorder traverses the AST. If postorder traversal
-/// is needed, the \c shouldTraversePostOrder method needs to be overriden
+/// is needed, the \c shouldTraversePostOrder method needs to be overridden
/// to return \c true.
template <typename Derived> class RecursiveASTVisitor {
public:
@@ -158,25 +158,25 @@ public:
typedef SmallVectorImpl<llvm::PointerIntPair<Stmt *, 1, bool>>
DataRecursionQueue;
- /// \brief Return a reference to the derived class.
+ /// Return a reference to the derived class.
Derived &getDerived() { return *static_cast<Derived *>(this); }
- /// \brief Return whether this visitor should recurse into
+ /// 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
+ /// Return whether this visitor should recurse into the types of
/// TypeLocs.
bool shouldWalkTypesOfTypeLocs() const { return true; }
- /// \brief Return whether this visitor should recurse into implicit
+ /// Return whether this visitor should recurse into implicit
/// code, e.g., implicit constructors and destructors.
bool shouldVisitImplicitCode() const { return false; }
- /// \brief Return whether this visitor should traverse post-order.
+ /// Return whether this visitor should traverse post-order.
bool shouldTraversePostOrder() const { return false; }
- /// \brief Recursively visit a statement or expression, by
+ /// 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
@@ -195,70 +195,70 @@ public:
/// \returns false if the visitation was terminated early, true otherwise.
bool dataTraverseStmtPost(Stmt *S) { return true; }
- /// \brief Recursively visit a type, by dispatching to
+ /// 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
+ /// 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
+ /// 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
+ /// 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.
+ /// 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
+ /// 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.
+ /// 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
+ /// 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
+ /// 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
+ /// 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.
+ /// 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.
///
@@ -267,13 +267,13 @@ public:
bool TraverseTemplateArguments(const TemplateArgument *Args,
unsigned NumArgs);
- /// \brief Recursively visit a base specifier. This can be overridden by a
+ /// Recursively visit a base specifier. This can be overridden by a
/// subclass.
///
/// \returns false if the visitation was terminated early, true otherwise.
bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base);
- /// \brief Recursively visit a constructor initializer. This
+ /// 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.
@@ -281,14 +281,14 @@ public:
/// \returns false if the visitation was terminated early, true otherwise.
bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
- /// \brief Recursively visit a lambda capture. \c Init is the expression that
+ /// Recursively visit a lambda capture. \c Init is the expression that
/// will be used to initialize the capture.
///
/// \returns false if the visitation was terminated early, true otherwise.
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
Expr *Init);
- /// \brief Recursively visit the body of a lambda expression.
+ /// Recursively visit the body of a lambda expression.
///
/// This provides a hook for visitors that need more context when visiting
/// \c LE->getBody().
@@ -296,7 +296,7 @@ public:
/// \returns false if the visitation was terminated early, true otherwise.
bool TraverseLambdaBody(LambdaExpr *LE, DataRecursionQueue *Queue = nullptr);
- /// \brief Recursively visit the syntactic or semantic form of an
+ /// Recursively visit the syntactic or semantic form of an
/// initialization list.
///
/// \returns false if the visitation was terminated early, true otherwise.
@@ -305,7 +305,7 @@ public:
// ---- Methods on Attrs ----
- // \brief Visit an attribute.
+ // Visit an attribute.
bool VisitAttr(Attr *A) { return true; }
// Declare Traverse* and empty Visit* for all Attr classes.
@@ -529,7 +529,7 @@ private:
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.
+ /// Process clauses with list of variables.
template <typename T> bool VisitOMPClauseList(T *Node);
/// Process clauses with pre-initis.
bool VisitOMPClauseWithPreInit(OMPClauseWithPreInit *Node);
@@ -993,6 +993,12 @@ DEF_TRAVERSE_TYPE(DependentAddressSpaceType, {
TRY_TO(TraverseType(T->getPointeeType()));
})
+DEF_TRAVERSE_TYPE(DependentVectorType, {
+ if (T->getSizeExpr())
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+ TRY_TO(TraverseType(T->getElementType()));
+})
+
DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
if (T->getSizeExpr())
TRY_TO(TraverseStmt(T->getSizeExpr()));
@@ -1221,6 +1227,12 @@ DEF_TRAVERSE_TYPELOC(VectorType, {
TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
})
+DEF_TRAVERSE_TYPELOC(DependentVectorType, {
+ if (TL.getTypePtr()->getSizeExpr())
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
// FIXME: size and attributes
// FIXME: base VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(ExtVectorType, {
@@ -2585,6 +2597,7 @@ DEF_TRAVERSE_STMT(CoyieldExpr, {
// These literals (all of them) do not need any action.
DEF_TRAVERSE_STMT(IntegerLiteral, {})
+DEF_TRAVERSE_STMT(FixedPointLiteral, {})
DEF_TRAVERSE_STMT(CharacterLiteral, {})
DEF_TRAVERSE_STMT(FloatingLiteral, {})
DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index 86b0f356e7b53..c2bd6e6fd1361 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -36,7 +36,7 @@ class Decl;
// DeclLink that may point to one of 3 possible states:
// - the "previous" (temporal) element in the chain
// - the "latest" (temporal) element in the chain
-// - the an "uninitialized-latest" value (when newly-constructed)
+// - the "uninitialized-latest" value (when newly-constructed)
//
// - The first element is also often called the canonical element. Every
// element has a pointer to it so that "getCanonical" can be fast.
@@ -48,10 +48,8 @@ class Decl;
// "most-recent" when referring to temporal order: order of addition
// to the chain.
//
-// - To make matters confusing, the DeclLink type uses the term "next"
-// for its pointer-storage internally (thus functions like
-// NextIsPrevious). It's easiest to just ignore the implementation of
-// DeclLink when making sense of the redeclaration chain.
+// - It's easiest to just ignore the implementation of DeclLink when making
+// sense of the redeclaration chain.
//
// - There's also a "definition" link for several types of
// redeclarable, where only one definition should exist at any given
@@ -82,7 +80,7 @@ class Decl;
// | link +-----+ |
// +-->-------------------------------------------+
-/// \brief Provides common interface for the Decls that can be redeclared.
+/// Provides common interface for the Decls that can be redeclared.
template<typename decl_type>
class Redeclarable {
protected:
@@ -105,66 +103,64 @@ protected:
/// previous declaration.
using NotKnownLatest = llvm::PointerUnion<Previous, UninitializedLatest>;
- mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
+ mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Link;
public:
enum PreviousTag { PreviousLink };
enum LatestTag { LatestLink };
DeclLink(LatestTag, const ASTContext &Ctx)
- : Next(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
- DeclLink(PreviousTag, decl_type *D) : Next(NotKnownLatest(Previous(D))) {}
+ : Link(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
+ DeclLink(PreviousTag, decl_type *D) : Link(NotKnownLatest(Previous(D))) {}
- bool NextIsPrevious() const {
- return Next.is<NotKnownLatest>() &&
+ bool isFirst() const {
+ return Link.is<KnownLatest>() ||
// FIXME: 'template' is required on the next line due to an
// apparent clang bug.
- Next.get<NotKnownLatest>().template is<Previous>();
+ Link.get<NotKnownLatest>().template is<UninitializedLatest>();
}
- bool NextIsLatest() const { return !NextIsPrevious(); }
-
- decl_type *getNext(const decl_type *D) const {
- if (Next.is<NotKnownLatest>()) {
- NotKnownLatest NKL = Next.get<NotKnownLatest>();
+ decl_type *getPrevious(const decl_type *D) const {
+ if (Link.is<NotKnownLatest>()) {
+ NotKnownLatest NKL = Link.get<NotKnownLatest>();
if (NKL.is<Previous>())
return static_cast<decl_type*>(NKL.get<Previous>());
// Allocate the generational 'most recent' cache now, if needed.
- Next = KnownLatest(*reinterpret_cast<const ASTContext *>(
+ Link = KnownLatest(*reinterpret_cast<const ASTContext *>(
NKL.get<UninitializedLatest>()),
const_cast<decl_type *>(D));
}
- return static_cast<decl_type*>(Next.get<KnownLatest>().get(D));
+ return static_cast<decl_type*>(Link.get<KnownLatest>().get(D));
}
void setPrevious(decl_type *D) {
- assert(NextIsPrevious() && "decl became non-canonical unexpectedly");
- Next = Previous(D);
+ assert(!isFirst() && "decl became non-canonical unexpectedly");
+ Link = Previous(D);
}
void setLatest(decl_type *D) {
- assert(NextIsLatest() && "decl became canonical unexpectedly");
- if (Next.is<NotKnownLatest>()) {
- NotKnownLatest NKL = Next.get<NotKnownLatest>();
- Next = KnownLatest(*reinterpret_cast<const ASTContext *>(
+ assert(isFirst() && "decl became canonical unexpectedly");
+ if (Link.is<NotKnownLatest>()) {
+ NotKnownLatest NKL = Link.get<NotKnownLatest>();
+ Link = KnownLatest(*reinterpret_cast<const ASTContext *>(
NKL.get<UninitializedLatest>()),
D);
} else {
- auto Latest = Next.get<KnownLatest>();
+ auto Latest = Link.get<KnownLatest>();
Latest.set(D);
- Next = Latest;
+ Link = Latest;
}
}
- void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); }
+ void markIncomplete() { Link.get<KnownLatest>().markIncomplete(); }
Decl *getLatestNotUpdated() const {
- assert(NextIsLatest() && "expected a canonical decl");
- if (Next.is<NotKnownLatest>())
+ assert(isFirst() && "expected a canonical decl");
+ if (Link.is<NotKnownLatest>())
return nullptr;
- return Next.get<KnownLatest>().getNotUpdated();
+ return Link.get<KnownLatest>().getNotUpdated();
}
};
@@ -176,10 +172,10 @@ protected:
return DeclLink(DeclLink::LatestLink, Ctx);
}
- /// \brief Points to the next redeclaration in the chain.
+ /// Points to the next redeclaration in the chain.
///
- /// If NextIsPrevious() is true, this is a link to the previous declaration
- /// of this same Decl. If NextIsLatest() is true, this is the first
+ /// If isFirst() is false, this is a link to the previous declaration
+ /// of this same Decl. If isFirst() is true, this is the first
/// declaration and Link points to the latest declaration. For example:
///
/// #1 int f(int x, int y = 1); // <pointer to #3, true>
@@ -192,7 +188,7 @@ protected:
decl_type *First;
decl_type *getNextRedeclaration() const {
- return RedeclLink.getNext(static_cast<const decl_type *>(this));
+ return RedeclLink.getPrevious(static_cast<const decl_type *>(this));
}
public:
@@ -203,10 +199,10 @@ public:
: RedeclLink(LatestDeclLink(Ctx)),
First(static_cast<decl_type *>(this)) {}
- /// \brief Return the previous declaration of this declaration or NULL if this
+ /// Return the previous declaration of this declaration or NULL if this
/// is the first declaration.
decl_type *getPreviousDecl() {
- if (RedeclLink.NextIsPrevious())
+ if (!RedeclLink.isFirst())
return getNextRedeclaration();
return nullptr;
}
@@ -215,32 +211,32 @@ public:
static_cast<const decl_type*>(this))->getPreviousDecl();
}
- /// \brief Return the first declaration of this declaration or itself if this
+ /// Return the first declaration of this declaration or itself if this
/// is the only declaration.
decl_type *getFirstDecl() { return First; }
- /// \brief Return the first declaration of this declaration or itself if this
+ /// Return the first declaration of this declaration or itself if this
/// is the only declaration.
const decl_type *getFirstDecl() const { return First; }
- /// \brief True if this is the first declaration in its redeclaration chain.
- bool isFirstDecl() const { return RedeclLink.NextIsLatest(); }
+ /// True if this is the first declaration in its redeclaration chain.
+ bool isFirstDecl() const { return RedeclLink.isFirst(); }
- /// \brief Returns the most recent (re)declaration of this declaration.
+ /// Returns the most recent (re)declaration of this declaration.
decl_type *getMostRecentDecl() {
return getFirstDecl()->getNextRedeclaration();
}
- /// \brief Returns the most recent (re)declaration of this declaration.
+ /// Returns the most recent (re)declaration of this declaration.
const decl_type *getMostRecentDecl() const {
return getFirstDecl()->getNextRedeclaration();
}
- /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
+ /// Set the previous declaration. If PrevDecl is NULL, set this as the
/// first and only declaration.
void setPreviousDecl(decl_type *PrevDecl);
- /// \brief Iterates through all the redeclarations of the same decl.
+ /// Iterates through all the redeclarations of the same decl.
class redecl_iterator {
/// Current - The current declaration.
decl_type *Current = nullptr;
@@ -294,7 +290,7 @@ public:
using redecl_range = llvm::iterator_range<redecl_iterator>;
- /// \brief Returns an iterator range for all the redeclarations of the same
+ /// 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(redecl_iterator(const_cast<decl_type *>(
@@ -306,11 +302,11 @@ public:
redecl_iterator redecls_end() const { return redecls().end(); }
};
-/// \brief Get the primary declaration for a declaration from an AST file. That
+/// Get the primary declaration for a declaration from an AST file. That
/// will be the first-loaded declaration.
Decl *getPrimaryMergedDecl(Decl *D);
-/// \brief Provides common interface for the Decls that cannot be redeclared,
+/// Provides common interface for the Decls that cannot be redeclared,
/// but can be merged if the same declaration is brought in from multiple
/// modules.
template<typename decl_type>
@@ -318,25 +314,25 @@ class Mergeable {
public:
Mergeable() = default;
- /// \brief Return the first declaration of this declaration or itself if this
+ /// Return the first declaration of this declaration or itself if this
/// is the only declaration.
decl_type *getFirstDecl() {
- decl_type *D = static_cast<decl_type*>(this);
+ auto *D = static_cast<decl_type *>(this);
if (!D->isFromASTFile())
return D;
return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
}
- /// \brief Return the first declaration of this declaration or itself if this
+ /// Return the first declaration of this declaration or itself if this
/// is the only declaration.
const decl_type *getFirstDecl() const {
- const decl_type *D = static_cast<const decl_type*>(this);
+ const auto *D = static_cast<const decl_type *>(this);
if (!D->isFromASTFile())
return D;
return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
}
- /// \brief Returns true if this is the first declaration.
+ /// Returns true if this is the first declaration.
bool isFirstDecl() const { return getFirstDecl() == this; }
};
diff --git a/include/clang/AST/SelectorLocationsKind.h b/include/clang/AST/SelectorLocationsKind.h
index 6d903f820cd49..6ca2dba47558f 100644
--- a/include/clang/AST/SelectorLocationsKind.h
+++ b/include/clang/AST/SelectorLocationsKind.h
@@ -23,32 +23,32 @@ namespace clang {
class Expr;
class ParmVarDecl;
-/// \brief Whether all locations of the selector identifiers are in a
+/// Whether all locations of the selector identifiers are in a
/// "standard" position.
enum SelectorLocationsKind {
- /// \brief Non-standard.
+ /// Non-standard.
SelLoc_NonStandard = 0,
- /// \brief For nullary selectors, immediately before the end:
+ /// For nullary selectors, immediately before the end:
/// "[foo release]" / "-(void)release;"
/// Or immediately before the arguments:
/// "[foo first:1 second:2]" / "-(id)first:(int)x second:(int)y;
SelLoc_StandardNoSpace = 1,
- /// \brief For nullary selectors, immediately before the end:
+ /// For nullary selectors, immediately before the end:
/// "[foo release]" / "-(void)release;"
/// Or with a space between the arguments:
/// "[foo first: 1 second: 2]" / "-(id)first: (int)x second: (int)y;
SelLoc_StandardWithSpace = 2
};
-/// \brief Returns true if all \p SelLocs are in a "standard" location.
+/// Returns true if all \p SelLocs are in a "standard" location.
SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
ArrayRef<SourceLocation> SelLocs,
ArrayRef<Expr *> Args,
SourceLocation EndLoc);
-/// \brief Get the "standard" location of a selector identifier, e.g:
+/// Get the "standard" location of a selector identifier, e.g:
/// For nullary selectors, immediately before ']': "[foo release]"
///
/// \param WithArgSpace if true the standard location is with a space apart
@@ -60,13 +60,13 @@ SourceLocation getStandardSelectorLoc(unsigned Index,
ArrayRef<Expr *> Args,
SourceLocation EndLoc);
-/// \brief Returns true if all \p SelLocs are in a "standard" location.
+/// Returns true if all \p SelLocs are in a "standard" location.
SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
ArrayRef<SourceLocation> SelLocs,
ArrayRef<ParmVarDecl *> Args,
SourceLocation EndLoc);
-/// \brief Get the "standard" location of a selector identifier, e.g:
+/// Get the "standard" location of a selector identifier, e.g:
/// For nullary selectors, immediately before ']': "[foo release]"
///
/// \param WithArgSpace if true the standard location is with a space apart
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index b27dbfacf6a64..91dbcb71a600c 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -92,7 +92,7 @@ protected:
class StmtBitfields {
friend class Stmt;
- /// \brief The statement class.
+ /// The statement class.
unsigned sClass : 8;
};
enum { NumStmtBits = 8 };
@@ -198,11 +198,13 @@ protected:
class CastExprBitfields {
friend class CastExpr;
+ friend class ImplicitCastExpr;
unsigned : NumExprBits;
unsigned Kind : 6;
- unsigned BasePathSize : 32 - 6 - NumExprBits;
+ unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.
+ unsigned BasePathSize : 32 - 6 - 1 - NumExprBits;
};
class CallExprBitfields {
@@ -237,6 +239,16 @@ protected:
unsigned ResultIndex : 32 - 8 - NumExprBits;
};
+ class OpaqueValueExprBitfields {
+ friend class OpaqueValueExpr;
+
+ unsigned : NumExprBits;
+
+ /// The OVE is a unique semantic reference to its source expressio if this
+ /// bit is set to true.
+ unsigned IsUnique : 1;
+ };
+
class ObjCIndirectCopyRestoreExprBitfields {
friend class ObjCIndirectCopyRestoreExpr;
@@ -262,14 +274,14 @@ protected:
unsigned : NumExprBits;
- /// \brief The kind of type trait, which is a value of a TypeTrait enumerator.
+ /// The kind of type trait, which is a value of a TypeTrait enumerator.
unsigned Kind : 8;
- /// \brief If this expression is not value-dependent, this indicates whether
+ /// If this expression is not value-dependent, this indicates whether
/// the trait evaluated true or false.
unsigned Value : 1;
- /// \brief The number of arguments to this type trait.
+ /// The number of arguments to this type trait.
unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
};
@@ -294,6 +306,7 @@ protected:
CallExprBitfields CallExprBits;
ExprWithCleanupsBitfields ExprWithCleanupsBits;
PseudoObjectExprBitfields PseudoObjectExprBits;
+ OpaqueValueExprBitfields OpaqueValueExprBits;
ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
InitListExprBitfields InitListExprBits;
TypeTraitExprBitfields TypeTraitExprBits;
@@ -319,7 +332,7 @@ public:
void operator delete(void *, void *) noexcept {}
public:
- /// \brief A placeholder type used to construct an empty shell of a
+ /// A placeholder type used to construct an empty shell of a
/// type, that will be filled in later (e.g., by some
/// de-serialization).
struct EmptyShell {};
@@ -358,11 +371,11 @@ protected:
};
private:
- /// \brief Whether statistic collection is enabled.
+ /// Whether statistic collection is enabled.
static bool StatisticsEnabled;
protected:
- /// \brief Construct an empty statement.
+ /// Construct an empty statement.
explicit Stmt(StmtClass SC, EmptyShell) : Stmt(SC) {}
public:
@@ -393,7 +406,7 @@ public:
static void EnableStatistics();
static void PrintStats();
- /// \brief Dumps the specified AST fragment and all subtrees to
+ /// Dumps the specified AST fragment and all subtrees to
/// \c llvm::errs().
void dump() const;
void dump(SourceManager &SM) const;
@@ -421,7 +434,7 @@ public:
return const_cast<Stmt *>(this)->IgnoreImplicit();
}
- /// \brief Skip no-op (attributed, compound) container stmts and skip captured
+ /// Skip no-op (attributed, compound) container stmts and skip captured
/// stmt at the top, if \a IgnoreCaptured is true.
Stmt *IgnoreContainers(bool IgnoreCaptured = false);
const Stmt *IgnoreContainers(bool IgnoreCaptured = false) const {
@@ -444,6 +457,7 @@ public:
using const_child_range = llvm::iterator_range<const_child_iterator>;
child_range children();
+
const_child_range children() const {
auto Children = const_cast<Stmt *>(this)->children();
return const_child_range(Children.begin(), Children.end());
@@ -455,7 +469,7 @@ public:
const_child_iterator child_begin() const { return children().begin(); }
const_child_iterator child_end() const { return children().end(); }
- /// \brief Produce a unique representation of the given statement.
+ /// Produce a unique representation of the given statement.
///
/// \param ID once the profiling operation is complete, will contain
/// the unique representation of the given statement.
@@ -470,7 +484,7 @@ public:
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
bool Canonical) const;
- /// \brief Calculate a unique representation for a statement that is
+ /// Calculate a unique representation for a statement that is
/// stable across compiler invocations.
///
/// \param ID profile information will be stored in ID.
@@ -492,7 +506,7 @@ public:
DeclStmt(DeclGroupRef dg, SourceLocation startLoc, SourceLocation endLoc)
: Stmt(DeclStmtClass), DG(dg), StartLoc(startLoc), EndLoc(endLoc) {}
- /// \brief Build an empty declaration statement.
+ /// Build an empty declaration statement.
explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) {}
/// isSingleDecl - This method returns true if this DeclStmt refers
@@ -532,9 +546,11 @@ public:
using decl_const_range = llvm::iterator_range<const_decl_iterator>;
decl_range decls() { return decl_range(decl_begin(), decl_end()); }
+
decl_const_range decls() const {
return decl_const_range(decl_begin(), decl_end());
}
+
decl_iterator decl_begin() { return DG.begin(); }
decl_iterator decl_end() { return DG.end(); }
const_decl_iterator decl_begin() const { return DG.begin(); }
@@ -556,7 +572,7 @@ public:
class NullStmt : public Stmt {
SourceLocation SemiLoc;
- /// \brief True if the null statement was preceded by an empty macro, e.g:
+ /// True if the null statement was preceded by an empty macro, e.g:
/// @code
/// #define CALL(x)
/// CALL(0);
@@ -571,7 +587,7 @@ public:
: Stmt(NullStmtClass), SemiLoc(L),
HasLeadingEmptyMacro(hasLeadingEmptyMacro) {}
- /// \brief Build an empty null statement.
+ /// Build an empty null statement.
explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) {}
SourceLocation getSemiLoc() const { return SemiLoc; }
@@ -608,13 +624,13 @@ public:
static CompoundStmt *Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
SourceLocation LB, SourceLocation RB);
- // \brief Build an empty compound statement with a location.
+ // Build an empty compound statement with a location.
explicit CompoundStmt(SourceLocation Loc)
: Stmt(CompoundStmtClass), LBraceLoc(Loc), RBraceLoc(Loc) {
CompoundStmtBits.NumStmts = 0;
}
- // \brief Build an empty compound statement.
+ // Build an empty compound statement.
static CompoundStmt *CreateEmpty(const ASTContext &C, unsigned NumStmts);
bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
@@ -627,6 +643,7 @@ public:
body_iterator body_begin() { return getTrailingObjects<Stmt *>(); }
body_iterator body_end() { return body_begin() + size(); }
Stmt *body_front() { return !body_empty() ? body_begin()[0] : nullptr; }
+
Stmt *body_back() {
return !body_empty() ? body_begin()[size() - 1] : nullptr;
}
@@ -646,6 +663,7 @@ public:
const_body_iterator body_begin() const {
return getTrailingObjects<Stmt *>();
}
+
const_body_iterator body_end() const { return body_begin() + size(); }
const Stmt *body_front() const {
@@ -751,7 +769,7 @@ public:
EllipsisLoc = ellipsisLoc;
}
- /// \brief Build an empty switch case statement.
+ /// Build an empty switch case statement.
explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass, Empty) {}
SourceLocation getCaseLoc() const { return KeywordLoc; }
@@ -784,7 +802,7 @@ public:
SourceLocation getLocEnd() const LLVM_READONLY {
// Handle deeply nested case statements with iteration instead of recursion.
const CaseStmt *CS = this;
- while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
+ while (const auto *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
CS = CS2;
return CS->getSubStmt()->getLocEnd();
@@ -807,7 +825,7 @@ public:
DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}
- /// \brief Build an empty default statement.
+ /// Build an empty default statement.
explicit DefaultStmt(EmptyShell Empty)
: SwitchCase(DefaultStmtClass, Empty) {}
@@ -832,7 +850,7 @@ public:
};
inline SourceLocation SwitchCase::getLocEnd() const {
- if (const CaseStmt *CS = dyn_cast<CaseStmt>(this))
+ if (const auto *CS = dyn_cast<CaseStmt>(this))
return CS->getLocEnd();
return cast<DefaultStmt>(this)->getLocEnd();
}
@@ -852,7 +870,7 @@ public:
"LabelStmt too big");
}
- // \brief Build an empty label statement.
+ // Build an empty label statement.
explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) {}
SourceLocation getIdentLoc() const { return IdentLoc; }
@@ -874,7 +892,7 @@ public:
}
};
-/// \brief Represents an attribute applied to a statement.
+/// Represents an attribute applied to a statement.
///
/// Represents an attribute applied to a statement. For example:
/// [[omp::for(...)]] for (...) { ... }
@@ -895,7 +913,7 @@ class AttributedStmt final
}
explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
- : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) {
+ : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) {
std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr);
}
@@ -908,7 +926,7 @@ public:
static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
ArrayRef<const Attr*> Attrs, Stmt *SubStmt);
- // \brief Build an empty attributed statement.
+ // Build an empty attributed statement.
static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs);
SourceLocation getAttrLoc() const { return AttrLoc; }
@@ -943,10 +961,10 @@ public:
Stmt *then, SourceLocation EL = SourceLocation(),
Stmt *elsev = nullptr);
- /// \brief Build an empty if/then/else statement
+ /// Build an empty if/then/else statement
explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) {}
- /// \brief Retrieve the variable declared in this "if" statement, if any.
+ /// Retrieve the variable declared in this "if" statement, if any.
///
/// In the following example, "x" is the condition variable.
/// \code
@@ -1022,10 +1040,10 @@ class SwitchStmt : public Stmt {
public:
SwitchStmt(const ASTContext &C, Stmt *Init, VarDecl *Var, Expr *cond);
- /// \brief Build a empty switch statement.
+ /// Build a empty switch statement.
explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) {}
- /// \brief Retrieve the variable declared in this "switch" statement, if any.
+ /// Retrieve the variable declared in this "switch" statement, if any.
///
/// In the following example, "x" is the condition variable.
/// \code
@@ -1056,7 +1074,7 @@ public:
void setBody(Stmt *S) { SubExprs[BODY] = S; }
SwitchCase *getSwitchCaseList() { return FirstCase.getPointer(); }
- /// \brief Set the case list for this switch statement.
+ /// Set the case list for this switch statement.
void setSwitchCaseList(SwitchCase *SC) { FirstCase.setPointer(SC); }
SourceLocation getSwitchLoc() const { return SwitchLoc; }
@@ -1108,10 +1126,10 @@ public:
WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
SourceLocation WL);
- /// \brief Build an empty while statement.
+ /// Build an empty while statement.
explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) {}
- /// \brief Retrieve the variable declared in this "while" statement, if any.
+ /// Retrieve the variable declared in this "while" statement, if any.
///
/// In the following example, "x" is the condition variable.
/// \code
@@ -1170,7 +1188,7 @@ public:
SubExprs[BODY] = body;
}
- /// \brief Build an empty do-while statement.
+ /// Build an empty do-while statement.
explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) {}
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
@@ -1215,12 +1233,12 @@ public:
Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
SourceLocation RP);
- /// \brief Build an empty for statement.
+ /// Build an empty for statement.
explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) {}
Stmt *getInit() { return SubExprs[INIT]; }
- /// \brief Retrieve the variable declared in this "for" statement, if any.
+ /// Retrieve the variable declared in this "for" statement, if any.
///
/// In the following example, "y" is the condition variable.
/// \code
@@ -1284,7 +1302,7 @@ public:
GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL)
: Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
- /// \brief Build an empty goto statement.
+ /// Build an empty goto statement.
explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) {}
LabelDecl *getLabel() const { return Label; }
@@ -1320,7 +1338,7 @@ public:
: Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
Target((Stmt*)target) {}
- /// \brief Build an empty indirect goto statement.
+ /// Build an empty indirect goto statement.
explicit IndirectGotoStmt(EmptyShell Empty)
: Stmt(IndirectGotoStmtClass, Empty) {}
@@ -1358,7 +1376,7 @@ class ContinueStmt : public Stmt {
public:
ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
- /// \brief Build an empty continue statement.
+ /// Build an empty continue statement.
explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) {}
SourceLocation getContinueLoc() const { return ContinueLoc; }
@@ -1387,7 +1405,7 @@ public:
"BreakStmt too large");
}
- /// \brief Build an empty break statement.
+ /// Build an empty break statement.
explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) {}
SourceLocation getBreakLoc() const { return BreakLoc; }
@@ -1426,7 +1444,7 @@ public:
: Stmt(ReturnStmtClass), RetLoc(RL), RetExpr((Stmt *)E),
NRVOCandidate(NRVOCandidate) {}
- /// \brief Build an empty return expression.
+ /// Build an empty return expression.
explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) {}
const Expr *getRetValue() const;
@@ -1436,7 +1454,7 @@ public:
SourceLocation getReturnLoc() const { return RetLoc; }
void setReturnLoc(SourceLocation L) { RetLoc = L; }
- /// \brief Retrieve the variable that might be used for the named return
+ /// Retrieve the variable that might be used for the named return
/// value optimization.
///
/// The optimization itself can only be performed if the variable is
@@ -1468,11 +1486,11 @@ protected:
SourceLocation AsmLoc;
- /// \brief True if the assembly statement does not have any input or output
+ /// True if the assembly statement does not have any input or output
/// operands.
bool IsSimple;
- /// \brief If true, treat this inline assembly as having side effects.
+ /// If true, treat this inline assembly as having side effects.
/// This assembly statement should not be optimized, deleted or moved.
bool IsVolatile;
@@ -1489,7 +1507,7 @@ protected:
NumClobbers(numclobbers) {}
public:
- /// \brief Build an empty inline-assembly statement.
+ /// Build an empty inline-assembly statement.
explicit AsmStmt(StmtClass SC, EmptyShell Empty) : Stmt(SC, Empty) {}
SourceLocation getAsmLoc() const { return AsmLoc; }
@@ -1501,8 +1519,8 @@ public:
bool isVolatile() const { return IsVolatile; }
void setVolatile(bool V) { IsVolatile = V; }
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getLocStart() const LLVM_READONLY { return {}; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return {}; }
//===--- Asm String Analysis ---===//
@@ -1635,7 +1653,7 @@ public:
StringLiteral *asmstr, unsigned numclobbers,
StringLiteral **clobbers, SourceLocation rparenloc);
- /// \brief Build an empty inline-assembly statement.
+ /// Build an empty inline-assembly statement.
explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty) {}
SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -1675,9 +1693,7 @@ public:
bool isString() const { return MyKind == String; }
bool isOperand() const { return MyKind == Operand; }
- const std::string &getString() const {
- return Str;
- }
+ const std::string &getString() const { return Str; }
unsigned getOperandNo() const {
assert(isOperand());
@@ -1707,15 +1723,13 @@ public:
//===--- Output operands ---===//
- IdentifierInfo *getOutputIdentifier(unsigned i) const {
- return Names[i];
- }
+ IdentifierInfo *getOutputIdentifier(unsigned i) const { return Names[i]; }
StringRef getOutputName(unsigned i) const {
if (IdentifierInfo *II = getOutputIdentifier(i))
return II->getName();
- return StringRef();
+ return {};
}
StringRef getOutputConstraint(unsigned i) const;
@@ -1743,7 +1757,7 @@ public:
if (IdentifierInfo *II = getInputIdentifier(i))
return II->getName();
- return StringRef();
+ return {};
}
StringRef getInputConstraint(unsigned i) const;
@@ -1816,7 +1830,7 @@ public:
ArrayRef<Expr*> exprs, StringRef asmstr,
ArrayRef<StringRef> clobbers, SourceLocation endloc);
- /// \brief Build an empty MS-style inline-assembly statement.
+ /// Build an empty MS-style inline-assembly statement.
explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty) {}
SourceLocation getLBraceLoc() const { return LBraceLoc; }
@@ -1930,7 +1944,7 @@ public:
}
child_range children() {
- return child_range(Children,Children+2);
+ return child_range(Children, Children+2);
}
static bool classof(const Stmt *T) {
@@ -2011,7 +2025,7 @@ public:
SEHFinallyStmt *getFinallyHandler() const;
child_range children() {
- return child_range(Children,Children+2);
+ return child_range(Children, Children+2);
}
static bool classof(const Stmt *T) {
@@ -2027,7 +2041,7 @@ public:
explicit SEHLeaveStmt(SourceLocation LL)
: Stmt(SEHLeaveStmtClass), LeaveLoc(LL) {}
- /// \brief Build an empty __leave statement.
+ /// Build an empty __leave statement.
explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) {}
SourceLocation getLeaveLoc() const { return LeaveLoc; }
@@ -2046,7 +2060,7 @@ public:
}
};
-/// \brief This captures a statement into a function. For example, the following
+/// This captures a statement into a function. For example, the following
/// pragma annotated compound statement can be represented as a CapturedStmt,
/// and this compound statement is the body of an anonymous outlined function.
/// @code
@@ -2057,7 +2071,7 @@ public:
/// @endcode
class CapturedStmt : public Stmt {
public:
- /// \brief The different capture forms: by 'this', by reference, capture for
+ /// The different capture forms: by 'this', by reference, capture for
/// variable-length array type etc.
enum VariableCaptureKind {
VCK_This,
@@ -2066,7 +2080,7 @@ public:
VCK_VLAType,
};
- /// \brief Describes the capture of either a variable, or 'this', or
+ /// Describes the capture of either a variable, or 'this', or
/// variable-length array type.
class Capture {
llvm::PointerIntPair<VarDecl *, 2, VariableCaptureKind> VarAndKind;
@@ -2075,7 +2089,7 @@ public:
public:
friend class ASTStmtReader;
- /// \brief Create a new capture.
+ /// Create a new capture.
///
/// \param Loc The source location associated with this capture.
///
@@ -2085,52 +2099,52 @@ public:
Capture(SourceLocation Loc, VariableCaptureKind Kind,
VarDecl *Var = nullptr);
- /// \brief Determine the kind of capture.
+ /// Determine the kind of capture.
VariableCaptureKind getCaptureKind() const;
- /// \brief Retrieve the source location at which the variable or 'this' was
+ /// Retrieve the source location at which the variable or 'this' was
/// first used.
SourceLocation getLocation() const { return Loc; }
- /// \brief Determine whether this capture handles the C++ 'this' pointer.
+ /// Determine whether this capture handles the C++ 'this' pointer.
bool capturesThis() const { return getCaptureKind() == VCK_This; }
- /// \brief Determine whether this capture handles a variable (by reference).
+ /// Determine whether this capture handles a variable (by reference).
bool capturesVariable() const { return getCaptureKind() == VCK_ByRef; }
- /// \brief Determine whether this capture handles a variable by copy.
+ /// Determine whether this capture handles a variable by copy.
bool capturesVariableByCopy() const {
return getCaptureKind() == VCK_ByCopy;
}
- /// \brief Determine whether this capture handles a variable-length array
+ /// Determine whether this capture handles a variable-length array
/// type.
bool capturesVariableArrayType() const {
return getCaptureKind() == VCK_VLAType;
}
- /// \brief Retrieve the declaration of the variable being captured.
+ /// Retrieve the declaration of the variable being captured.
///
/// This operation is only valid if this capture captures a variable.
VarDecl *getCapturedVar() const;
};
private:
- /// \brief The number of variable captured, including 'this'.
+ /// The number of variable captured, including 'this'.
unsigned NumCaptures;
- /// \brief The pointer part is the implicit the outlined function and the
+ /// The pointer part is the implicit the outlined function and the
/// int part is the captured region kind, 'CR_Default' etc.
- llvm::PointerIntPair<CapturedDecl *, 1, CapturedRegionKind> CapDeclAndKind;
+ llvm::PointerIntPair<CapturedDecl *, 2, CapturedRegionKind> CapDeclAndKind;
- /// \brief The record for captured variables, a RecordDecl or CXXRecordDecl.
+ /// The record for captured variables, a RecordDecl or CXXRecordDecl.
RecordDecl *TheRecordDecl = nullptr;
- /// \brief Construct a captured statement.
+ /// Construct a captured statement.
CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures,
ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD);
- /// \brief Construct an empty captured statement.
+ /// Construct an empty captured statement.
CapturedStmt(EmptyShell Empty, unsigned NumCaptures);
Stmt **getStoredStmts() { return reinterpret_cast<Stmt **>(this + 1); }
@@ -2155,36 +2169,36 @@ public:
static CapturedStmt *CreateDeserialized(const ASTContext &Context,
unsigned NumCaptures);
- /// \brief Retrieve the statement being captured.
+ /// Retrieve the statement being captured.
Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; }
const Stmt *getCapturedStmt() const { return getStoredStmts()[NumCaptures]; }
- /// \brief Retrieve the outlined function declaration.
+ /// Retrieve the outlined function declaration.
CapturedDecl *getCapturedDecl();
const CapturedDecl *getCapturedDecl() const;
- /// \brief Set the outlined function declaration.
+ /// Set the outlined function declaration.
void setCapturedDecl(CapturedDecl *D);
- /// \brief Retrieve the captured region kind.
+ /// Retrieve the captured region kind.
CapturedRegionKind getCapturedRegionKind() const;
- /// \brief Set the captured region kind.
+ /// Set the captured region kind.
void setCapturedRegionKind(CapturedRegionKind Kind);
- /// \brief Retrieve the record declaration for captured variables.
+ /// Retrieve the record declaration for captured variables.
const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; }
- /// \brief Set the record declaration for captured variables.
+ /// Set the record declaration for captured variables.
void setCapturedRecordDecl(RecordDecl *D) {
assert(D && "null RecordDecl");
TheRecordDecl = D;
}
- /// \brief True if this variable has been captured.
+ /// True if this variable has been captured.
bool capturesVariable(const VarDecl *Var) const;
- /// \brief An iterator that walks over the captures.
+ /// An iterator that walks over the captures.
using capture_iterator = Capture *;
using const_capture_iterator = const Capture *;
using capture_range = llvm::iterator_range<capture_iterator>;
@@ -2197,24 +2211,24 @@ public:
return capture_const_range(capture_begin(), capture_end());
}
- /// \brief Retrieve an iterator pointing to the first capture.
+ /// Retrieve an iterator pointing to the first capture.
capture_iterator capture_begin() { return getStoredCaptures(); }
const_capture_iterator capture_begin() const { return getStoredCaptures(); }
- /// \brief Retrieve an iterator pointing past the end of the sequence of
+ /// Retrieve an iterator pointing past the end of the sequence of
/// captures.
capture_iterator capture_end() const {
return getStoredCaptures() + NumCaptures;
}
- /// \brief Retrieve the number of captures, including 'this'.
+ /// Retrieve the number of captures, including 'this'.
unsigned capture_size() const { return NumCaptures; }
- /// \brief Iterator that walks over the capture initialization arguments.
+ /// Iterator that walks over the capture initialization arguments.
using capture_init_iterator = Expr **;
using capture_init_range = llvm::iterator_range<capture_init_iterator>;
- /// \brief Const iterator that walks over the capture initialization
+ /// Const iterator that walks over the capture initialization
/// arguments.
using const_capture_init_iterator = Expr *const *;
using const_capture_init_range =
@@ -2228,7 +2242,7 @@ public:
return const_capture_init_range(capture_init_begin(), capture_init_end());
}
- /// \brief Retrieve the first initialization argument.
+ /// Retrieve the first initialization argument.
capture_init_iterator capture_init_begin() {
return reinterpret_cast<Expr **>(getStoredStmts());
}
@@ -2237,7 +2251,7 @@ public:
return reinterpret_cast<Expr *const *>(getStoredStmts());
}
- /// \brief Retrieve the iterator pointing one past the last initialization
+ /// Retrieve the iterator pointing one past the last initialization
/// argument.
capture_init_iterator capture_init_end() {
return capture_init_begin() + NumCaptures;
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index 77f81838e5eb6..34553741eb38e 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -62,21 +62,22 @@ public:
/// CXXTryStmt - A C++ try block, including all handlers.
///
-class CXXTryStmt : public Stmt {
+class CXXTryStmt final : public Stmt,
+ private llvm::TrailingObjects<CXXTryStmt, Stmt *> {
+
+ friend TrailingObjects;
+ friend class ASTStmtReader;
+
SourceLocation TryLoc;
unsigned NumHandlers;
+ size_t numTrailingObjects(OverloadToken<Stmt *>) const { return NumHandlers; }
CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers);
-
CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
: Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
- Stmt const * const *getStmts() const {
- return reinterpret_cast<Stmt const * const*>(this + 1);
- }
- Stmt **getStmts() {
- return reinterpret_cast<Stmt **>(this + 1);
- }
+ Stmt *const *getStmts() const { return getTrailingObjects<Stmt *>(); }
+ Stmt **getStmts() { return getTrailingObjects<Stmt *>(); }
public:
static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc,
@@ -115,8 +116,6 @@ public:
child_range children() {
return child_range(getStmts(), getStmts() + getNumHandlers() + 1);
}
-
- friend class ASTStmtReader;
};
/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
@@ -210,7 +209,7 @@ public:
}
};
-/// \brief Representation of a Microsoft __if_exists or __if_not_exists
+/// Representation of a Microsoft __if_exists or __if_not_exists
/// statement with a dependent name.
///
/// The __if_exists statement can be used to include a sequence of statements
@@ -257,25 +256,25 @@ public:
QualifierLoc(QualifierLoc), NameInfo(NameInfo),
SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { }
- /// \brief Retrieve the location of the __if_exists or __if_not_exists
+ /// Retrieve the location of the __if_exists or __if_not_exists
/// keyword.
SourceLocation getKeywordLoc() const { return KeywordLoc; }
- /// \brief Determine whether this is an __if_exists statement.
+ /// Determine whether this is an __if_exists statement.
bool isIfExists() const { return IsIfExists; }
- /// \brief Determine whether this is an __if_exists statement.
+ /// Determine whether this is an __if_exists statement.
bool isIfNotExists() const { return !IsIfExists; }
- /// \brief Retrieve the nested-name-specifier that qualifies this name, if
+ /// Retrieve the nested-name-specifier that qualifies this name, if
/// any.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// \brief Retrieve the name of the entity we're testing for, along with
+ /// Retrieve the name of the entity we're testing for, along with
/// location information
DeclarationNameInfo getNameInfo() const { return NameInfo; }
- /// \brief Retrieve the compound statement that will be included in the
+ /// Retrieve the compound statement that will be included in the
/// program only if the existence of the symbol matches the initial keyword.
CompoundStmt *getSubStmt() const {
return reinterpret_cast<CompoundStmt *>(SubStmt);
@@ -293,7 +292,7 @@ public:
}
};
-/// \brief Represents the body of a coroutine. This wraps the normal function
+/// Represents the body of a coroutine. This wraps the normal function
/// body and holds the additional semantic context required to set up and tear
/// down the coroutine frame.
class CoroutineBodyStmt final
@@ -355,7 +354,7 @@ public:
return getPromiseDecl()->getType()->isDependentType();
}
- /// \brief Retrieve the body of the coroutine as written. This will be either
+ /// Retrieve the body of the coroutine as written. This will be either
/// a CompoundStmt or a TryStmt.
Stmt *getBody() const {
return getStoredStmts()[SubStmt::Body];
@@ -418,7 +417,7 @@ public:
}
};
-/// \brief Represents a 'co_return' statement in the C++ Coroutines TS.
+/// Represents a 'co_return' statement in the C++ Coroutines TS.
///
/// This statament models the initialization of the coroutine promise
/// (encapsulating the eventual notional return value) from an expression
@@ -451,11 +450,11 @@ public:
SourceLocation getKeywordLoc() const { return CoreturnLoc; }
- /// \brief Retrieve the operand of the 'co_return' statement. Will be nullptr
+ /// Retrieve the operand of the 'co_return' statement. Will be nullptr
/// if none was specified.
Expr *getOperand() const { return static_cast<Expr*>(SubStmts[Operand]); }
- /// \brief Retrieve the promise call that results from this 'co_return'
+ /// Retrieve the promise call that results from this 'co_return'
/// statement. Will be nullptr if either the coroutine has not yet been
/// finalized or the coroutine has no eventual return type.
Expr *getPromiseCall() const {
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
index 5260b6985bf58..571ad76be8a9d 100644
--- a/include/clang/AST/StmtObjC.h
+++ b/include/clang/AST/StmtObjC.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
/// \file
-/// \brief Defines the Objective-C statement AST node classes.
+/// Defines the Objective-C statement AST node classes.
#ifndef LLVM_CLANG_AST_STMTOBJC_H
#define LLVM_CLANG_AST_STMTOBJC_H
@@ -18,7 +18,7 @@
namespace clang {
-/// \brief Represents Objective-C's collection statement.
+/// Represents Objective-C's collection statement.
///
/// This is represented as 'for (element 'in' collection-expression)' stmt.
class ObjCForCollectionStmt : public Stmt {
@@ -70,7 +70,7 @@ public:
}
};
-/// \brief Represents Objective-C's \@catch statement.
+/// Represents Objective-C's \@catch statement.
class ObjCAtCatchStmt : public Stmt {
private:
VarDecl *ExceptionDecl;
@@ -116,7 +116,7 @@ public:
child_range children() { return child_range(&Body, &Body + 1); }
};
-/// \brief Represents Objective-C's \@finally statement
+/// Represents Objective-C's \@finally statement
class ObjCAtFinallyStmt : public Stmt {
SourceLocation AtFinallyLoc;
Stmt *AtFinallyStmt;
@@ -150,7 +150,7 @@ public:
}
};
-/// \brief Represents Objective-C's \@try ... \@catch ... \@finally statement.
+/// Represents Objective-C's \@try ... \@catch ... \@finally statement.
class ObjCAtTryStmt : public Stmt {
private:
// The location of the @ in the \@try.
@@ -162,7 +162,7 @@ private:
// Whether this statement has a \@finally statement.
bool HasFinally : 1;
- /// \brief Retrieve the statements that are stored after this \@try statement.
+ /// Retrieve the statements that are stored after this \@try statement.
///
/// The order of the statements in memory follows the order in the source,
/// with the \@try body first, followed by the \@catch statements (if any)
@@ -189,38 +189,38 @@ public:
static ObjCAtTryStmt *CreateEmpty(const ASTContext &Context,
unsigned NumCatchStmts, bool HasFinally);
- /// \brief Retrieve the location of the @ in the \@try.
+ /// Retrieve the location of the @ in the \@try.
SourceLocation getAtTryLoc() const { return AtTryLoc; }
void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; }
- /// \brief Retrieve the \@try body.
+ /// Retrieve the \@try body.
const Stmt *getTryBody() const { return getStmts()[0]; }
Stmt *getTryBody() { return getStmts()[0]; }
void setTryBody(Stmt *S) { getStmts()[0] = S; }
- /// \brief Retrieve the number of \@catch statements in this try-catch-finally
+ /// Retrieve the number of \@catch statements in this try-catch-finally
/// block.
unsigned getNumCatchStmts() const { return NumCatchStmts; }
- /// \brief Retrieve a \@catch statement.
+ /// Retrieve a \@catch statement.
const ObjCAtCatchStmt *getCatchStmt(unsigned I) const {
assert(I < NumCatchStmts && "Out-of-bounds @catch index");
return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
}
- /// \brief Retrieve a \@catch statement.
+ /// Retrieve a \@catch statement.
ObjCAtCatchStmt *getCatchStmt(unsigned I) {
assert(I < NumCatchStmts && "Out-of-bounds @catch index");
return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
}
- /// \brief Set a particular catch statement.
+ /// Set a particular catch statement.
void setCatchStmt(unsigned I, ObjCAtCatchStmt *S) {
assert(I < NumCatchStmts && "Out-of-bounds @catch index");
getStmts()[I + 1] = S;
}
- /// \brief Retrieve the \@finally statement, if any.
+ /// Retrieve the \@finally statement, if any.
const ObjCAtFinallyStmt *getFinallyStmt() const {
if (!HasFinally)
return nullptr;
@@ -251,7 +251,7 @@ public:
}
};
-/// \brief Represents Objective-C's \@synchronized statement.
+/// Represents Objective-C's \@synchronized statement.
///
/// Example:
/// \code
@@ -309,7 +309,7 @@ public:
}
};
-/// \brief Represents Objective-C's \@throw statement.
+/// Represents Objective-C's \@throw statement.
class ObjCAtThrowStmt : public Stmt {
SourceLocation AtThrowLoc;
Stmt *Throw;
@@ -341,7 +341,7 @@ public:
child_range children() { return child_range(&Throw, &Throw+1); }
};
-/// \brief Represents Objective-C's \@autoreleasepool Statement
+/// Represents Objective-C's \@autoreleasepool Statement
class ObjCAutoreleasePoolStmt : public Stmt {
SourceLocation AtLoc;
Stmt *SubStmt;
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index 66fb037fc33cb..84a35db938b06 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
/// \file
-/// \brief This file defines OpenMP AST classes for executable directives and
+/// This file defines OpenMP AST classes for executable directives and
/// clauses.
///
//===----------------------------------------------------------------------===//
@@ -27,28 +27,28 @@ namespace clang {
// AST classes for directives.
//===----------------------------------------------------------------------===//
-/// \brief This is a basic class for representing single OpenMP executable
+/// This is a basic class for representing single OpenMP executable
/// directive.
///
class OMPExecutableDirective : public Stmt {
friend class ASTStmtReader;
- /// \brief Kind of the directive.
+ /// Kind of the directive.
OpenMPDirectiveKind Kind;
- /// \brief Starting location of the directive (directive keyword).
+ /// Starting location of the directive (directive keyword).
SourceLocation StartLoc;
- /// \brief Ending location of the directive.
+ /// Ending location of the directive.
SourceLocation EndLoc;
- /// \brief Numbers of clauses.
+ /// Numbers of clauses.
const unsigned NumClauses;
- /// \brief Number of child expressions/stmts.
+ /// Number of child expressions/stmts.
const unsigned NumChildren;
- /// \brief Offset from this to the start of clauses.
+ /// Offset from this to the start of clauses.
/// There are NumClauses pointers to clauses, they are followed by
/// NumChildren pointers to child stmts/exprs (if the directive type
/// requires an associated stmt, then it has to be the first of them).
const unsigned ClausesOffset;
- /// \brief Get the clauses storage.
+ /// Get the clauses storage.
MutableArrayRef<OMPClause *> getClauses() {
OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
reinterpret_cast<char *>(this) + ClausesOffset);
@@ -56,7 +56,7 @@ class OMPExecutableDirective : public Stmt {
}
protected:
- /// \brief Build instance of directive of class \a K.
+ /// Build instance of directive of class \a K.
///
/// \param SC Statement class.
/// \param K Kind of OpenMP directive.
@@ -72,13 +72,13 @@ protected:
NumChildren(NumChildren),
ClausesOffset(llvm::alignTo(sizeof(T), alignof(OMPClause *))) {}
- /// \brief Sets the list of variables for this clause.
+ /// Sets the list of variables for this clause.
///
/// \param Clauses The list of clauses for the directive.
///
void setClauses(ArrayRef<OMPClause *> Clauses);
- /// \brief Set the associated statement for the directive.
+ /// Set the associated statement for the directive.
///
/// /param S Associated statement.
///
@@ -88,7 +88,7 @@ protected:
}
public:
- /// \brief Iterates over a filtered subrange of clauses applied to a
+ /// Iterates over a filtered subrange of clauses applied to a
/// directive.
///
/// This iterator visits only clauses of type SpecificClause.
@@ -164,45 +164,49 @@ public:
return Clauses.begin() != Clauses.end();
}
- /// \brief Returns starting location of directive kind.
+ /// Returns starting location of directive kind.
SourceLocation getLocStart() const { return StartLoc; }
- /// \brief Returns ending location of directive.
+ /// Returns ending location of directive.
SourceLocation getLocEnd() const { return EndLoc; }
- /// \brief Set starting location of directive kind.
+ /// Set starting location of directive kind.
///
/// \param Loc New starting location of directive.
///
void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
- /// \brief Set ending location of directive.
+ /// Set ending location of directive.
///
/// \param Loc New ending location of directive.
///
void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
- /// \brief Get number of clauses.
+ /// Get number of clauses.
unsigned getNumClauses() const { return NumClauses; }
- /// \brief Returns specified clause.
+ /// Returns specified clause.
///
/// \param i Number of clause.
///
OMPClause *getClause(unsigned i) const { return clauses()[i]; }
- /// \brief Returns true if directive has associated statement.
+ /// Returns true if directive has associated statement.
bool hasAssociatedStmt() const { return NumChildren > 0; }
- /// \brief Returns statement associated with the directive.
- Stmt *getAssociatedStmt() const {
+ /// Returns statement associated with the directive.
+ const Stmt *getAssociatedStmt() const {
assert(hasAssociatedStmt() && "no associated statement.");
- return const_cast<Stmt *>(*child_begin());
+ return *child_begin();
+ }
+ Stmt *getAssociatedStmt() {
+ assert(hasAssociatedStmt() && "no associated statement.");
+ return *child_begin();
}
- /// \brief Returns the captured statement associated with the
+ /// Returns the captured statement associated with the
/// component region within the (combined) directive.
//
// \param RegionKind Component region kind.
- CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
+ const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
assert(std::any_of(
@@ -218,6 +222,25 @@ public:
llvm_unreachable("Incorrect RegionKind specified for directive.");
}
+ /// Get innermost captured statement for the construct.
+ CapturedStmt *getInnermostCapturedStmt() {
+ assert(hasAssociatedStmt() && getAssociatedStmt() &&
+ "Must have associated statement.");
+ SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
+ getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
+ assert(!CaptureRegions.empty() &&
+ "At least one captured statement must be provided.");
+ auto *CS = cast<CapturedStmt>(getAssociatedStmt());
+ for (unsigned Level = CaptureRegions.size(); Level > 1; --Level)
+ CS = cast<CapturedStmt>(CS->getCapturedStmt());
+ return CS;
+ }
+
+ const CapturedStmt *getInnermostCapturedStmt() const {
+ return const_cast<OMPExecutableDirective *>(this)
+ ->getInnermostCapturedStmt();
+ }
+
OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
static bool classof(const Stmt *S) {
@@ -229,7 +252,9 @@ public:
if (!hasAssociatedStmt())
return child_range(child_iterator(), child_iterator());
Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
- return child_range(ChildStorage, ChildStorage + NumChildren);
+ /// Do not mark all the special expression/statements as children, except
+ /// for the associated statement.
+ return child_range(ChildStorage, ChildStorage + 1);
}
ArrayRef<OMPClause *> clauses() { return getClauses(); }
@@ -239,7 +264,7 @@ public:
}
};
-/// \brief This represents '#pragma omp parallel' directive.
+/// This represents '#pragma omp parallel' directive.
///
/// \code
/// #pragma omp parallel private(a,b) reduction(+: c,d)
@@ -250,10 +275,10 @@ public:
///
class OMPParallelDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief true if the construct has inner cancel directive.
+ /// true if the construct has inner cancel directive.
bool HasCancel;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive (directive keyword).
/// \param EndLoc Ending Location of the directive.
@@ -264,7 +289,7 @@ class OMPParallelDirective : public OMPExecutableDirective {
StartLoc, EndLoc, NumClauses, 1),
HasCancel(false) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -274,11 +299,11 @@ class OMPParallelDirective : public OMPExecutableDirective {
1),
HasCancel(false) {}
- /// \brief Set cancel state.
+ /// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -291,7 +316,7 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
- /// \brief Creates an empty directive with the place for \a N clauses.
+ /// Creates an empty directive with the place for \a N clauses.
///
/// \param C AST context.
/// \param NumClauses Number of clauses.
@@ -299,7 +324,7 @@ public:
static OMPParallelDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell);
- /// \brief Return true if current directive has inner cancel directive.
+ /// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) {
@@ -307,15 +332,15 @@ public:
}
};
-/// \brief This is a common base class for loop directives ('omp simd', 'omp
+/// This is a common base class for loop directives ('omp simd', 'omp
/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
///
class OMPLoopDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Number of collapsed loops as specified by 'collapse' clause.
+ /// Number of collapsed loops as specified by 'collapse' clause.
unsigned CollapsedNum;
- /// \brief Offsets to the stored exprs.
+ /// Offsets to the stored exprs.
/// This enumeration contains offsets to all the pointers to children
/// expressions stored in OMPLoopDirective.
/// The first 9 children are necessary for all the loop directives,
@@ -372,21 +397,21 @@ class OMPLoopDirective : public OMPExecutableDirective {
CombinedDistributeEnd = 28,
};
- /// \brief Get the counters storage.
+ /// Get the counters storage.
MutableArrayRef<Expr *> getCounters() {
Expr **Storage = reinterpret_cast<Expr **>(
&(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
return MutableArrayRef<Expr *>(Storage, CollapsedNum);
}
- /// \brief Get the private counters storage.
+ /// Get the private counters storage.
MutableArrayRef<Expr *> getPrivateCounters() {
Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
return MutableArrayRef<Expr *>(Storage, CollapsedNum);
}
- /// \brief Get the updates storage.
+ /// Get the updates storage.
MutableArrayRef<Expr *> getInits() {
Expr **Storage = reinterpret_cast<Expr **>(
&*std::next(child_begin(),
@@ -394,7 +419,7 @@ class OMPLoopDirective : public OMPExecutableDirective {
return MutableArrayRef<Expr *>(Storage, CollapsedNum);
}
- /// \brief Get the updates storage.
+ /// Get the updates storage.
MutableArrayRef<Expr *> getUpdates() {
Expr **Storage = reinterpret_cast<Expr **>(
&*std::next(child_begin(),
@@ -402,7 +427,7 @@ class OMPLoopDirective : public OMPExecutableDirective {
return MutableArrayRef<Expr *>(Storage, CollapsedNum);
}
- /// \brief Get the final counter updates storage.
+ /// Get the final counter updates storage.
MutableArrayRef<Expr *> getFinals() {
Expr **Storage = reinterpret_cast<Expr **>(
&*std::next(child_begin(),
@@ -411,7 +436,7 @@ class OMPLoopDirective : public OMPExecutableDirective {
}
protected:
- /// \brief Build instance of loop directive of class \a Kind.
+ /// Build instance of loop directive of class \a Kind.
///
/// \param SC Statement class.
/// \param Kind Kind of OpenMP directive.
@@ -431,7 +456,7 @@ protected:
NumSpecialChildren),
CollapsedNum(CollapsedNum) {}
- /// \brief Offset to the start of children expression arrays.
+ /// Offset to the start of children expression arrays.
static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
if (isOpenMPLoopBoundSharingDirective(Kind))
return CombinedDistributeEnd;
@@ -441,7 +466,7 @@ protected:
return DefaultEnd;
}
- /// \brief Children number.
+ /// Children number.
static unsigned numLoopChildren(unsigned CollapsedNum,
OpenMPDirectiveKind Kind) {
return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
@@ -606,72 +631,72 @@ public:
/// Distribute Loop condition used when composing 'omp distribute'
/// with 'omp for' in a same construct
Expr *Cond;
- /// Update of LowerBound for statically sheduled omp loops for
+ /// Update of LowerBound for statically scheduled omp loops for
/// outer loop in combined constructs (e.g. 'distribute parallel for')
Expr *NLB;
- /// Update of UpperBound for statically sheduled omp loops for
+ /// Update of UpperBound for statically scheduled omp loops for
/// outer loop in combined constructs (e.g. 'distribute parallel for')
Expr *NUB;
};
- /// \brief The expressions built for the OpenMP loop CodeGen for the
+ /// The expressions built for the OpenMP loop CodeGen for the
/// whole collapsed loop nest.
struct HelperExprs {
- /// \brief Loop iteration variable.
+ /// Loop iteration variable.
Expr *IterationVarRef;
- /// \brief Loop last iteration number.
+ /// Loop last iteration number.
Expr *LastIteration;
- /// \brief Loop number of iterations.
+ /// Loop number of iterations.
Expr *NumIterations;
- /// \brief Calculation of last iteration.
+ /// Calculation of last iteration.
Expr *CalcLastIteration;
- /// \brief Loop pre-condition.
+ /// Loop pre-condition.
Expr *PreCond;
- /// \brief Loop condition.
+ /// Loop condition.
Expr *Cond;
- /// \brief Loop iteration variable init.
+ /// Loop iteration variable init.
Expr *Init;
- /// \brief Loop increment.
+ /// Loop increment.
Expr *Inc;
- /// \brief IsLastIteration - local flag variable passed to runtime.
+ /// IsLastIteration - local flag variable passed to runtime.
Expr *IL;
- /// \brief LowerBound - local variable passed to runtime.
+ /// LowerBound - local variable passed to runtime.
Expr *LB;
- /// \brief UpperBound - local variable passed to runtime.
+ /// UpperBound - local variable passed to runtime.
Expr *UB;
- /// \brief Stride - local variable passed to runtime.
+ /// Stride - local variable passed to runtime.
Expr *ST;
- /// \brief EnsureUpperBound -- expression UB = min(UB, NumIterations).
+ /// EnsureUpperBound -- expression UB = min(UB, NumIterations).
Expr *EUB;
- /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
+ /// Update of LowerBound for statically scheduled 'omp for' loops.
Expr *NLB;
- /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
+ /// Update of UpperBound for statically scheduled 'omp for' loops.
Expr *NUB;
- /// \brief PreviousLowerBound - local variable passed to runtime in the
+ /// PreviousLowerBound - local variable passed to runtime in the
/// enclosing schedule or null if that does not apply.
Expr *PrevLB;
- /// \brief PreviousUpperBound - local variable passed to runtime in the
+ /// PreviousUpperBound - local variable passed to runtime in the
/// enclosing schedule or null if that does not apply.
Expr *PrevUB;
- /// \brief DistInc - increment expression for distribute loop when found
+ /// DistInc - increment expression for distribute loop when found
/// combined with a further loop level (e.g. in 'distribute parallel for')
/// expression IV = IV + ST
Expr *DistInc;
- /// \brief PrevEUB - expression similar to EUB but to be used when loop
+ /// PrevEUB - expression similar to EUB but to be used when loop
/// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for'
/// when ensuring that the UB is either the calculated UB by the runtime or
/// the end of the assigned distribute chunk)
/// expression UB = min (UB, PrevUB)
Expr *PrevEUB;
- /// \brief Counters Loop counters.
+ /// Counters Loop counters.
SmallVector<Expr *, 4> Counters;
- /// \brief PrivateCounters Loop counters.
+ /// PrivateCounters Loop counters.
SmallVector<Expr *, 4> PrivateCounters;
- /// \brief Expressions for loop counters inits for CodeGen.
+ /// Expressions for loop counters inits for CodeGen.
SmallVector<Expr *, 4> Inits;
- /// \brief Expressions for loop counters update for CodeGen.
+ /// Expressions for loop counters update for CodeGen.
SmallVector<Expr *, 4> Updates;
- /// \brief Final loop counter values for GodeGen.
+ /// Final loop counter values for GodeGen.
SmallVector<Expr *, 4> Finals;
/// Init statement for all captured expressions.
Stmt *PreInits;
@@ -679,7 +704,7 @@ public:
/// Expressions used when combining OpenMP loop pragmas
DistCombinedHelperExprs DistCombinedFields;
- /// \brief Check if all the expressions are built (does not check the
+ /// Check if all the expressions are built (does not check the
/// worksharing ones).
bool builtAll() {
return IterationVarRef != nullptr && LastIteration != nullptr &&
@@ -687,7 +712,7 @@ public:
Cond != nullptr && Init != nullptr && Inc != nullptr;
}
- /// \brief Initialize all the fields to null.
+ /// Initialize all the fields to null.
/// \param Size Number of elements in the counters/finals/updates arrays.
void clear(unsigned Size) {
IterationVarRef = nullptr;
@@ -732,7 +757,7 @@ public:
}
};
- /// \brief Get number of collapsed loops.
+ /// Get number of collapsed loops.
unsigned getCollapsedNumber() const { return CollapsedNum; }
Expr *getIterationVariable() const {
@@ -899,9 +924,8 @@ public:
}
const Stmt *getBody() const {
// This relies on the loop form is already checked by Sema.
- const Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
- while(const auto *CS = dyn_cast<CapturedStmt>(Body))
- Body = CS->getCapturedStmt();
+ const Stmt *Body =
+ getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers();
Body = cast<ForStmt>(Body)->getBody();
for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
Body = Body->IgnoreContainers();
@@ -969,7 +993,7 @@ public:
}
};
-/// \brief This represents '#pragma omp simd' directive.
+/// This represents '#pragma omp simd' directive.
///
/// \code
/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
@@ -980,7 +1004,7 @@ public:
///
class OMPSimdDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -992,7 +1016,7 @@ class OMPSimdDirective : public OMPLoopDirective {
: OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
EndLoc, CollapsedNum, NumClauses) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
@@ -1003,7 +1027,7 @@ class OMPSimdDirective : public OMPLoopDirective {
NumClauses) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1019,7 +1043,7 @@ public:
Stmt *AssociatedStmt,
const HelperExprs &Exprs);
- /// \brief Creates an empty directive with the place
+ /// Creates an empty directive with the place
/// for \a NumClauses clauses.
///
/// \param C AST context.
@@ -1034,7 +1058,7 @@ public:
}
};
-/// \brief This represents '#pragma omp for' directive.
+/// This represents '#pragma omp for' directive.
///
/// \code
/// #pragma omp for private(a,b) reduction(+:c,d)
@@ -1046,10 +1070,10 @@ public:
class OMPForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief true if current directive has inner cancel directive.
+ /// true if current directive has inner cancel directive.
bool HasCancel;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1062,7 +1086,7 @@ class OMPForDirective : public OMPLoopDirective {
CollapsedNum, NumClauses),
HasCancel(false) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
@@ -1072,11 +1096,11 @@ class OMPForDirective : public OMPLoopDirective {
SourceLocation(), CollapsedNum, NumClauses),
HasCancel(false) {}
- /// \brief Set cancel state.
+ /// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1093,7 +1117,7 @@ public:
Stmt *AssociatedStmt, const HelperExprs &Exprs,
bool HasCancel);
- /// \brief Creates an empty directive with the place
+ /// Creates an empty directive with the place
/// for \a NumClauses clauses.
///
/// \param C AST context.
@@ -1103,7 +1127,7 @@ public:
static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
unsigned CollapsedNum, EmptyShell);
- /// \brief Return true if current directive has inner cancel directive.
+ /// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) {
@@ -1111,7 +1135,7 @@ public:
}
};
-/// \brief This represents '#pragma omp for simd' directive.
+/// This represents '#pragma omp for simd' directive.
///
/// \code
/// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
@@ -1122,7 +1146,7 @@ public:
///
class OMPForSimdDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1134,7 +1158,7 @@ class OMPForSimdDirective : public OMPLoopDirective {
: OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
StartLoc, EndLoc, CollapsedNum, NumClauses) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
@@ -1145,7 +1169,7 @@ class OMPForSimdDirective : public OMPLoopDirective {
NumClauses) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1160,7 +1184,7 @@ public:
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
- /// \brief Creates an empty directive with the place
+ /// Creates an empty directive with the place
/// for \a NumClauses clauses.
///
/// \param C AST context.
@@ -1176,7 +1200,7 @@ public:
}
};
-/// \brief This represents '#pragma omp sections' directive.
+/// This represents '#pragma omp sections' directive.
///
/// \code
/// #pragma omp sections private(a,b) reduction(+:c,d)
@@ -1188,10 +1212,10 @@ public:
class OMPSectionsDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief true if current directive has inner cancel directive.
+ /// true if current directive has inner cancel directive.
bool HasCancel;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1203,7 +1227,7 @@ class OMPSectionsDirective : public OMPExecutableDirective {
StartLoc, EndLoc, NumClauses, 1),
HasCancel(false) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -1213,11 +1237,11 @@ class OMPSectionsDirective : public OMPExecutableDirective {
1),
HasCancel(false) {}
- /// \brief Set cancel state.
+ /// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1230,7 +1254,7 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
- /// \brief Creates an empty directive with the place for \a NumClauses
+ /// Creates an empty directive with the place for \a NumClauses
/// clauses.
///
/// \param C AST context.
@@ -1239,7 +1263,7 @@ public:
static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell);
- /// \brief Return true if current directive has inner cancel directive.
+ /// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) {
@@ -1247,7 +1271,7 @@ public:
}
};
-/// \brief This represents '#pragma omp section' directive.
+/// This represents '#pragma omp section' directive.
///
/// \code
/// #pragma omp section
@@ -1256,10 +1280,10 @@ public:
class OMPSectionDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief true if current directive has inner cancel directive.
+ /// true if current directive has inner cancel directive.
bool HasCancel;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1269,7 +1293,7 @@ class OMPSectionDirective : public OMPExecutableDirective {
StartLoc, EndLoc, 0, 1),
HasCancel(false) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
explicit OMPSectionDirective()
: OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
@@ -1277,7 +1301,7 @@ class OMPSectionDirective : public OMPExecutableDirective {
HasCancel(false) {}
public:
- /// \brief Creates directive.
+ /// Creates directive.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1290,16 +1314,16 @@ public:
SourceLocation EndLoc,
Stmt *AssociatedStmt, bool HasCancel);
- /// \brief Creates an empty directive.
+ /// Creates an empty directive.
///
/// \param C AST context.
///
static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
- /// \brief Set cancel state.
+ /// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
- /// \brief Return true if current directive has inner cancel directive.
+ /// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) {
@@ -1307,7 +1331,7 @@ public:
}
};
-/// \brief This represents '#pragma omp single' directive.
+/// This represents '#pragma omp single' directive.
///
/// \code
/// #pragma omp single private(a,b) copyprivate(c,d)
@@ -1317,7 +1341,7 @@ public:
///
class OMPSingleDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1328,7 +1352,7 @@ class OMPSingleDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
StartLoc, EndLoc, NumClauses, 1) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -1338,7 +1362,7 @@ class OMPSingleDirective : public OMPExecutableDirective {
1) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1350,7 +1374,7 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
- /// \brief Creates an empty directive with the place for \a NumClauses
+ /// Creates an empty directive with the place for \a NumClauses
/// clauses.
///
/// \param C AST context.
@@ -1364,7 +1388,7 @@ public:
}
};
-/// \brief This represents '#pragma omp master' directive.
+/// This represents '#pragma omp master' directive.
///
/// \code
/// #pragma omp master
@@ -1372,7 +1396,7 @@ public:
///
class OMPMasterDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1381,14 +1405,14 @@ class OMPMasterDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
StartLoc, EndLoc, 0, 1) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
explicit OMPMasterDirective()
: OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
SourceLocation(), SourceLocation(), 0, 1) {}
public:
- /// \brief Creates directive.
+ /// Creates directive.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1400,7 +1424,7 @@ public:
SourceLocation EndLoc,
Stmt *AssociatedStmt);
- /// \brief Creates an empty directive.
+ /// Creates an empty directive.
///
/// \param C AST context.
///
@@ -1411,7 +1435,7 @@ public:
}
};
-/// \brief This represents '#pragma omp critical' directive.
+/// This represents '#pragma omp critical' directive.
///
/// \code
/// #pragma omp critical
@@ -1419,9 +1443,9 @@ public:
///
class OMPCriticalDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Name of the directive.
+ /// Name of the directive.
DeclarationNameInfo DirName;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param Name Name of the directive.
/// \param StartLoc Starting location of the directive kind.
@@ -1434,7 +1458,7 @@ class OMPCriticalDirective : public OMPExecutableDirective {
StartLoc, EndLoc, NumClauses, 1),
DirName(Name) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -1444,14 +1468,14 @@ class OMPCriticalDirective : public OMPExecutableDirective {
1),
DirName() {}
- /// \brief Set name of the directive.
+ /// Set name of the directive.
///
/// \param Name Name of the directive.
///
void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
public:
- /// \brief Creates directive.
+ /// Creates directive.
///
/// \param C AST context.
/// \param Name Name of the directive.
@@ -1465,7 +1489,7 @@ public:
SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
- /// \brief Creates an empty directive.
+ /// Creates an empty directive.
///
/// \param C AST context.
/// \param NumClauses Number of clauses.
@@ -1473,7 +1497,7 @@ public:
static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell);
- /// \brief Return name of the directive.
+ /// Return name of the directive.
///
DeclarationNameInfo getDirectiveName() const { return DirName; }
@@ -1482,7 +1506,7 @@ public:
}
};
-/// \brief This represents '#pragma omp parallel for' directive.
+/// This represents '#pragma omp parallel for' directive.
///
/// \code
/// #pragma omp parallel for private(a,b) reduction(+:c,d)
@@ -1494,10 +1518,10 @@ public:
class OMPParallelForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief true if current region has inner cancel directive.
+ /// true if current region has inner cancel directive.
bool HasCancel;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1510,7 +1534,7 @@ class OMPParallelForDirective : public OMPLoopDirective {
StartLoc, EndLoc, CollapsedNum, NumClauses),
HasCancel(false) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
@@ -1521,11 +1545,11 @@ class OMPParallelForDirective : public OMPLoopDirective {
NumClauses),
HasCancel(false) {}
- /// \brief Set cancel state.
+ /// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1541,7 +1565,7 @@ public:
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
- /// \brief Creates an empty directive with the place
+ /// Creates an empty directive with the place
/// for \a NumClauses clauses.
///
/// \param C AST context.
@@ -1553,7 +1577,7 @@ public:
unsigned CollapsedNum,
EmptyShell);
- /// \brief Return true if current directive has inner cancel directive.
+ /// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) {
@@ -1561,7 +1585,7 @@ public:
}
};
-/// \brief This represents '#pragma omp parallel for simd' directive.
+/// This represents '#pragma omp parallel for simd' directive.
///
/// \code
/// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
@@ -1573,7 +1597,7 @@ public:
///
class OMPParallelForSimdDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1586,7 +1610,7 @@ class OMPParallelForSimdDirective : public OMPLoopDirective {
OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
NumClauses) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
@@ -1598,7 +1622,7 @@ class OMPParallelForSimdDirective : public OMPLoopDirective {
SourceLocation(), CollapsedNum, NumClauses) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1613,7 +1637,7 @@ public:
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
- /// \brief Creates an empty directive with the place
+ /// Creates an empty directive with the place
/// for \a NumClauses clauses.
///
/// \param C AST context.
@@ -1630,7 +1654,7 @@ public:
}
};
-/// \brief This represents '#pragma omp parallel sections' directive.
+/// This represents '#pragma omp parallel sections' directive.
///
/// \code
/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
@@ -1642,10 +1666,10 @@ public:
class OMPParallelSectionsDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief true if current directive has inner cancel directive.
+ /// true if current directive has inner cancel directive.
bool HasCancel;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1658,7 +1682,7 @@ class OMPParallelSectionsDirective : public OMPExecutableDirective {
NumClauses, 1),
HasCancel(false) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -1668,11 +1692,11 @@ class OMPParallelSectionsDirective : public OMPExecutableDirective {
SourceLocation(), NumClauses, 1),
HasCancel(false) {}
- /// \brief Set cancel state.
+ /// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1685,7 +1709,7 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
- /// \brief Creates an empty directive with the place for \a NumClauses
+ /// Creates an empty directive with the place for \a NumClauses
/// clauses.
///
/// \param C AST context.
@@ -1694,7 +1718,7 @@ public:
static OMPParallelSectionsDirective *
CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
- /// \brief Return true if current directive has inner cancel directive.
+ /// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) {
@@ -1702,7 +1726,7 @@ public:
}
};
-/// \brief This represents '#pragma omp task' directive.
+/// This represents '#pragma omp task' directive.
///
/// \code
/// #pragma omp task private(a,b) final(d)
@@ -1712,10 +1736,10 @@ public:
///
class OMPTaskDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief true if this directive has inner cancel directive.
+ /// true if this directive has inner cancel directive.
bool HasCancel;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1727,7 +1751,7 @@ class OMPTaskDirective : public OMPExecutableDirective {
EndLoc, NumClauses, 1),
HasCancel(false) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -1737,11 +1761,11 @@ class OMPTaskDirective : public OMPExecutableDirective {
1),
HasCancel(false) {}
- /// \brief Set cancel state.
+ /// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1755,7 +1779,7 @@ public:
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, bool HasCancel);
- /// \brief Creates an empty directive with the place for \a NumClauses
+ /// Creates an empty directive with the place for \a NumClauses
/// clauses.
///
/// \param C AST context.
@@ -1764,7 +1788,7 @@ public:
static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
EmptyShell);
- /// \brief Return true if current directive has inner cancel directive.
+ /// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) {
@@ -1772,7 +1796,7 @@ public:
}
};
-/// \brief This represents '#pragma omp taskyield' directive.
+/// This represents '#pragma omp taskyield' directive.
///
/// \code
/// #pragma omp taskyield
@@ -1780,7 +1804,7 @@ public:
///
class OMPTaskyieldDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1789,14 +1813,14 @@ class OMPTaskyieldDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
StartLoc, EndLoc, 0, 0) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
explicit OMPTaskyieldDirective()
: OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
SourceLocation(), SourceLocation(), 0, 0) {}
public:
- /// \brief Creates directive.
+ /// Creates directive.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1805,7 +1829,7 @@ public:
static OMPTaskyieldDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
- /// \brief Creates an empty directive.
+ /// Creates an empty directive.
///
/// \param C AST context.
///
@@ -1816,7 +1840,7 @@ public:
}
};
-/// \brief This represents '#pragma omp barrier' directive.
+/// This represents '#pragma omp barrier' directive.
///
/// \code
/// #pragma omp barrier
@@ -1824,7 +1848,7 @@ public:
///
class OMPBarrierDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1833,14 +1857,14 @@ class OMPBarrierDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
StartLoc, EndLoc, 0, 0) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
explicit OMPBarrierDirective()
: OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
SourceLocation(), SourceLocation(), 0, 0) {}
public:
- /// \brief Creates directive.
+ /// Creates directive.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1849,7 +1873,7 @@ public:
static OMPBarrierDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
- /// \brief Creates an empty directive.
+ /// Creates an empty directive.
///
/// \param C AST context.
///
@@ -1860,7 +1884,7 @@ public:
}
};
-/// \brief This represents '#pragma omp taskwait' directive.
+/// This represents '#pragma omp taskwait' directive.
///
/// \code
/// #pragma omp taskwait
@@ -1868,7 +1892,7 @@ public:
///
class OMPTaskwaitDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1877,14 +1901,14 @@ class OMPTaskwaitDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
StartLoc, EndLoc, 0, 0) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
explicit OMPTaskwaitDirective()
: OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
SourceLocation(), SourceLocation(), 0, 0) {}
public:
- /// \brief Creates directive.
+ /// Creates directive.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -1893,7 +1917,7 @@ public:
static OMPTaskwaitDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
- /// \brief Creates an empty directive.
+ /// Creates an empty directive.
///
/// \param C AST context.
///
@@ -1973,7 +1997,7 @@ public:
}
};
-/// \brief This represents '#pragma omp flush' directive.
+/// This represents '#pragma omp flush' directive.
///
/// \code
/// #pragma omp flush(a,b)
@@ -1985,7 +2009,7 @@ public:
/// FlushClause.
class OMPFlushDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -1996,7 +2020,7 @@ class OMPFlushDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
StartLoc, EndLoc, NumClauses, 0) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -2006,7 +2030,7 @@ class OMPFlushDirective : public OMPExecutableDirective {
0) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2018,7 +2042,7 @@ public:
SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses);
- /// \brief Creates an empty directive with the place for \a NumClauses
+ /// Creates an empty directive with the place for \a NumClauses
/// clauses.
///
/// \param C AST context.
@@ -2032,7 +2056,7 @@ public:
}
};
-/// \brief This represents '#pragma omp ordered' directive.
+/// This represents '#pragma omp ordered' directive.
///
/// \code
/// #pragma omp ordered
@@ -2040,7 +2064,7 @@ public:
///
class OMPOrderedDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -2051,7 +2075,7 @@ class OMPOrderedDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
StartLoc, EndLoc, NumClauses, 1) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -2061,7 +2085,7 @@ class OMPOrderedDirective : public OMPExecutableDirective {
1) {}
public:
- /// \brief Creates directive.
+ /// Creates directive.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2073,7 +2097,7 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
- /// \brief Creates an empty directive.
+ /// Creates an empty directive.
///
/// \param C AST context.
/// \param NumClauses Number of clauses.
@@ -2086,7 +2110,7 @@ public:
}
};
-/// \brief This represents '#pragma omp atomic' directive.
+/// This represents '#pragma omp atomic' directive.
///
/// \code
/// #pragma omp atomic capture
@@ -2095,7 +2119,7 @@ public:
///
class OMPAtomicDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
+ /// Used for 'atomic update' or 'atomic capture' constructs. They may
/// have atomic expressions of forms
/// \code
/// x = x binop expr;
@@ -2105,7 +2129,7 @@ class OMPAtomicDirective : public OMPExecutableDirective {
/// second. Required for correct codegen of non-associative operations (like
/// << or >>).
bool IsXLHSInRHSPart;
- /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
+ /// Used for 'atomic update' or 'atomic capture' constructs. They may
/// have atomic expressions of forms
/// \code
/// v = x; <update x>;
@@ -2115,7 +2139,7 @@ class OMPAtomicDirective : public OMPExecutableDirective {
/// otherwise.
bool IsPostfixUpdate;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -2127,7 +2151,7 @@ class OMPAtomicDirective : public OMPExecutableDirective {
StartLoc, EndLoc, NumClauses, 5),
IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -2137,19 +2161,19 @@ class OMPAtomicDirective : public OMPExecutableDirective {
5),
IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
- /// \brief Set 'x' part of the associated expression/statement.
+ /// Set 'x' part of the associated expression/statement.
void setX(Expr *X) { *std::next(child_begin()) = X; }
- /// \brief Set helper expression of the form
+ /// Set helper expression of the form
/// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
/// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
- /// \brief Set 'v' part of the associated expression/statement.
+ /// Set 'v' part of the associated expression/statement.
void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
- /// \brief Set 'expr' part of the associated expression/statement.
+ /// Set 'expr' part of the associated expression/statement.
void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
public:
- /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
+ /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
/// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
/// detailed description of 'x', 'v' and 'expr').
///
@@ -2173,7 +2197,7 @@ public:
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
- /// \brief Creates an empty directive with the place for \a NumClauses
+ /// Creates an empty directive with the place for \a NumClauses
/// clauses.
///
/// \param C AST context.
@@ -2182,12 +2206,12 @@ public:
static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell);
- /// \brief Get 'x' part of the associated expression/statement.
+ /// Get 'x' part of the associated expression/statement.
Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
const Expr *getX() const {
return cast_or_null<Expr>(*std::next(child_begin()));
}
- /// \brief Get helper expression of the form
+ /// Get helper expression of the form
/// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
/// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
Expr *getUpdateExpr() {
@@ -2196,19 +2220,19 @@ public:
const Expr *getUpdateExpr() const {
return cast_or_null<Expr>(*std::next(child_begin(), 2));
}
- /// \brief Return true if helper update expression has form
+ /// Return true if helper update expression has form
/// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
/// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
- /// \brief Return true if 'v' expression must be updated to original value of
+ /// Return true if 'v' expression must be updated to original value of
/// 'x', false if 'v' must be updated to the new value of 'x'.
bool isPostfixUpdate() const { return IsPostfixUpdate; }
- /// \brief Get 'v' part of the associated expression/statement.
+ /// Get 'v' part of the associated expression/statement.
Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
const Expr *getV() const {
return cast_or_null<Expr>(*std::next(child_begin(), 3));
}
- /// \brief Get 'expr' part of the associated expression/statement.
+ /// Get 'expr' part of the associated expression/statement.
Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
const Expr *getExpr() const {
return cast_or_null<Expr>(*std::next(child_begin(), 4));
@@ -2219,7 +2243,7 @@ public:
}
};
-/// \brief This represents '#pragma omp target' directive.
+/// This represents '#pragma omp target' directive.
///
/// \code
/// #pragma omp target if(a)
@@ -2229,7 +2253,7 @@ public:
///
class OMPTargetDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -2240,7 +2264,7 @@ class OMPTargetDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
StartLoc, EndLoc, NumClauses, 1) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -2250,7 +2274,7 @@ class OMPTargetDirective : public OMPExecutableDirective {
1) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2262,7 +2286,7 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
- /// \brief Creates an empty directive with the place for \a NumClauses
+ /// Creates an empty directive with the place for \a NumClauses
/// clauses.
///
/// \param C AST context.
@@ -2276,7 +2300,7 @@ public:
}
};
-/// \brief This represents '#pragma omp target data' directive.
+/// This represents '#pragma omp target data' directive.
///
/// \code
/// #pragma omp target data device(0) if(a) map(b[:])
@@ -2287,7 +2311,7 @@ public:
///
class OMPTargetDataDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
@@ -2299,7 +2323,7 @@ class OMPTargetDataDirective : public OMPExecutableDirective {
OMPD_target_data, StartLoc, EndLoc, NumClauses,
1) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -2309,7 +2333,7 @@ class OMPTargetDataDirective : public OMPExecutableDirective {
SourceLocation(), NumClauses, 1) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2321,7 +2345,7 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
- /// \brief Creates an empty directive with the place for \a N clauses.
+ /// Creates an empty directive with the place for \a N clauses.
///
/// \param C AST context.
/// \param N The number of clauses.
@@ -2334,7 +2358,7 @@ public:
}
};
-/// \brief This represents '#pragma omp target enter data' directive.
+/// This represents '#pragma omp target enter data' directive.
///
/// \code
/// #pragma omp target enter data device(0) if(a) map(b[:])
@@ -2345,7 +2369,7 @@ public:
///
class OMPTargetEnterDataDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
@@ -2357,7 +2381,7 @@ class OMPTargetEnterDataDirective : public OMPExecutableDirective {
OMPD_target_enter_data, StartLoc, EndLoc,
NumClauses, /*NumChildren=*/1) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -2368,7 +2392,7 @@ class OMPTargetEnterDataDirective : public OMPExecutableDirective {
/*NumChildren=*/1) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2380,7 +2404,7 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
- /// \brief Creates an empty directive with the place for \a N clauses.
+ /// Creates an empty directive with the place for \a N clauses.
///
/// \param C AST context.
/// \param N The number of clauses.
@@ -2393,7 +2417,7 @@ public:
}
};
-/// \brief This represents '#pragma omp target exit data' directive.
+/// This represents '#pragma omp target exit data' directive.
///
/// \code
/// #pragma omp target exit data device(0) if(a) map(b[:])
@@ -2404,7 +2428,7 @@ public:
///
class OMPTargetExitDataDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
@@ -2416,7 +2440,7 @@ class OMPTargetExitDataDirective : public OMPExecutableDirective {
OMPD_target_exit_data, StartLoc, EndLoc,
NumClauses, /*NumChildren=*/1) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -2427,7 +2451,7 @@ class OMPTargetExitDataDirective : public OMPExecutableDirective {
/*NumChildren=*/1) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2439,7 +2463,7 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
- /// \brief Creates an empty directive with the place for \a N clauses.
+ /// Creates an empty directive with the place for \a N clauses.
///
/// \param C AST context.
/// \param N The number of clauses.
@@ -2452,7 +2476,7 @@ public:
}
};
-/// \brief This represents '#pragma omp target parallel' directive.
+/// This represents '#pragma omp target parallel' directive.
///
/// \code
/// #pragma omp target parallel if(a)
@@ -2462,7 +2486,7 @@ public:
///
class OMPTargetParallelDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -2474,7 +2498,7 @@ class OMPTargetParallelDirective : public OMPExecutableDirective {
OMPD_target_parallel, StartLoc, EndLoc,
NumClauses, /*NumChildren=*/1) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -2485,7 +2509,7 @@ class OMPTargetParallelDirective : public OMPExecutableDirective {
/*NumChildren=*/1) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2497,7 +2521,7 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
- /// \brief Creates an empty directive with the place for \a NumClauses
+ /// Creates an empty directive with the place for \a NumClauses
/// clauses.
///
/// \param C AST context.
@@ -2511,7 +2535,7 @@ public:
}
};
-/// \brief This represents '#pragma omp target parallel for' directive.
+/// This represents '#pragma omp target parallel for' directive.
///
/// \code
/// #pragma omp target parallel for private(a,b) reduction(+:c,d)
@@ -2523,10 +2547,10 @@ public:
class OMPTargetParallelForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief true if current region has inner cancel directive.
+ /// true if current region has inner cancel directive.
bool HasCancel;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -2540,7 +2564,7 @@ class OMPTargetParallelForDirective : public OMPLoopDirective {
CollapsedNum, NumClauses),
HasCancel(false) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
@@ -2552,11 +2576,11 @@ class OMPTargetParallelForDirective : public OMPLoopDirective {
SourceLocation(), CollapsedNum, NumClauses),
HasCancel(false) {}
- /// \brief Set cancel state.
+ /// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2572,7 +2596,7 @@ public:
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
- /// \brief Creates an empty directive with the place
+ /// Creates an empty directive with the place
/// for \a NumClauses clauses.
///
/// \param C AST context.
@@ -2584,7 +2608,7 @@ public:
unsigned CollapsedNum,
EmptyShell);
- /// \brief Return true if current directive has inner cancel directive.
+ /// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) {
@@ -2592,7 +2616,7 @@ public:
}
};
-/// \brief This represents '#pragma omp teams' directive.
+/// This represents '#pragma omp teams' directive.
///
/// \code
/// #pragma omp teams if(a)
@@ -2602,7 +2626,7 @@ public:
///
class OMPTeamsDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -2613,7 +2637,7 @@ class OMPTeamsDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
StartLoc, EndLoc, NumClauses, 1) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -2623,7 +2647,7 @@ class OMPTeamsDirective : public OMPExecutableDirective {
1) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2636,7 +2660,7 @@ public:
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt);
- /// \brief Creates an empty directive with the place for \a NumClauses
+ /// Creates an empty directive with the place for \a NumClauses
/// clauses.
///
/// \param C AST context.
@@ -2650,7 +2674,7 @@ public:
}
};
-/// \brief This represents '#pragma omp cancellation point' directive.
+/// This represents '#pragma omp cancellation point' directive.
///
/// \code
/// #pragma omp cancellation point for
@@ -2660,7 +2684,7 @@ public:
class OMPCancellationPointDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
OpenMPDirectiveKind CancelRegion;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -2670,7 +2694,7 @@ class OMPCancellationPointDirective : public OMPExecutableDirective {
OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
CancelRegion(OMPD_unknown) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
explicit OMPCancellationPointDirective()
: OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
@@ -2678,12 +2702,12 @@ class OMPCancellationPointDirective : public OMPExecutableDirective {
SourceLocation(), 0, 0),
CancelRegion(OMPD_unknown) {}
- /// \brief Set cancel region for current cancellation point.
+ /// Set cancel region for current cancellation point.
/// \param CR Cancellation region.
void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
public:
- /// \brief Creates directive.
+ /// Creates directive.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2693,14 +2717,14 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
OpenMPDirectiveKind CancelRegion);
- /// \brief Creates an empty directive.
+ /// Creates an empty directive.
///
/// \param C AST context.
///
static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
EmptyShell);
- /// \brief Get cancellation region for the current cancellation point.
+ /// Get cancellation region for the current cancellation point.
OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
static bool classof(const Stmt *T) {
@@ -2708,7 +2732,7 @@ public:
}
};
-/// \brief This represents '#pragma omp cancel' directive.
+/// This represents '#pragma omp cancel' directive.
///
/// \code
/// #pragma omp cancel for
@@ -2718,7 +2742,7 @@ public:
class OMPCancelDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
OpenMPDirectiveKind CancelRegion;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -2730,7 +2754,7 @@ class OMPCancelDirective : public OMPExecutableDirective {
StartLoc, EndLoc, NumClauses, 0),
CancelRegion(OMPD_unknown) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
explicit OMPCancelDirective(unsigned NumClauses)
@@ -2739,12 +2763,12 @@ class OMPCancelDirective : public OMPExecutableDirective {
0),
CancelRegion(OMPD_unknown) {}
- /// \brief Set cancel region for current cancellation point.
+ /// Set cancel region for current cancellation point.
/// \param CR Cancellation region.
void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
public:
- /// \brief Creates directive.
+ /// Creates directive.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2755,7 +2779,7 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
- /// \brief Creates an empty directive.
+ /// Creates an empty directive.
///
/// \param C AST context.
/// \param NumClauses Number of clauses.
@@ -2763,7 +2787,7 @@ public:
static OMPCancelDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell);
- /// \brief Get cancellation region for the current cancellation point.
+ /// Get cancellation region for the current cancellation point.
OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
static bool classof(const Stmt *T) {
@@ -2771,7 +2795,7 @@ public:
}
};
-/// \brief This represents '#pragma omp taskloop' directive.
+/// This represents '#pragma omp taskloop' directive.
///
/// \code
/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
@@ -2782,7 +2806,7 @@ public:
///
class OMPTaskLoopDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -2794,7 +2818,7 @@ class OMPTaskLoopDirective : public OMPLoopDirective {
: OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
StartLoc, EndLoc, CollapsedNum, NumClauses) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
@@ -2805,7 +2829,7 @@ class OMPTaskLoopDirective : public OMPLoopDirective {
NumClauses) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2820,7 +2844,7 @@ public:
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
- /// \brief Creates an empty directive with the place
+ /// Creates an empty directive with the place
/// for \a NumClauses clauses.
///
/// \param C AST context.
@@ -2836,7 +2860,7 @@ public:
}
};
-/// \brief This represents '#pragma omp taskloop simd' directive.
+/// This represents '#pragma omp taskloop simd' directive.
///
/// \code
/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
@@ -2847,7 +2871,7 @@ public:
///
class OMPTaskLoopSimdDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -2860,7 +2884,7 @@ class OMPTaskLoopSimdDirective : public OMPLoopDirective {
OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
NumClauses) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
@@ -2871,7 +2895,7 @@ class OMPTaskLoopSimdDirective : public OMPLoopDirective {
CollapsedNum, NumClauses) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2886,7 +2910,7 @@ public:
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
- /// \brief Creates an empty directive with the place
+ /// Creates an empty directive with the place
/// for \a NumClauses clauses.
///
/// \param C AST context.
@@ -2903,7 +2927,7 @@ public:
}
};
-/// \brief This represents '#pragma omp distribute' directive.
+/// This represents '#pragma omp distribute' directive.
///
/// \code
/// #pragma omp distribute private(a,b)
@@ -2914,7 +2938,7 @@ public:
class OMPDistributeDirective : public OMPLoopDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -2927,7 +2951,7 @@ class OMPDistributeDirective : public OMPLoopDirective {
StartLoc, EndLoc, CollapsedNum, NumClauses)
{}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
@@ -2939,7 +2963,7 @@ class OMPDistributeDirective : public OMPLoopDirective {
{}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -2954,7 +2978,7 @@ public:
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
- /// \brief Creates an empty directive with the place
+ /// Creates an empty directive with the place
/// for \a NumClauses clauses.
///
/// \param C AST context.
@@ -2970,7 +2994,7 @@ public:
}
};
-/// \brief This represents '#pragma omp target update' directive.
+/// This represents '#pragma omp target update' directive.
///
/// \code
/// #pragma omp target update to(a) from(b) device(1)
@@ -2981,7 +3005,7 @@ public:
///
class OMPTargetUpdateDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
@@ -2993,7 +3017,7 @@ class OMPTargetUpdateDirective : public OMPExecutableDirective {
OMPD_target_update, StartLoc, EndLoc, NumClauses,
1) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
@@ -3003,7 +3027,7 @@ class OMPTargetUpdateDirective : public OMPExecutableDirective {
SourceLocation(), NumClauses, 1) {}
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -3015,7 +3039,7 @@ public:
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
- /// \brief Creates an empty directive with the place for \a NumClauses
+ /// Creates an empty directive with the place for \a NumClauses
/// clauses.
///
/// \param C AST context.
@@ -3029,7 +3053,7 @@ public:
}
};
-/// \brief This represents '#pragma omp distribute parallel for' composite
+/// This represents '#pragma omp distribute parallel for' composite
/// directive.
///
/// \code
@@ -3043,7 +3067,7 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective {
/// true if the construct has inner cancel directive.
bool HasCancel = false;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
@@ -3057,7 +3081,7 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective {
OMPD_distribute_parallel_for, StartLoc, EndLoc,
CollapsedNum, NumClauses), HasCancel(false) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
@@ -3073,7 +3097,7 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective {
void setHasCancel(bool Has) { HasCancel = Has; }
public:
- /// \brief Creates directive with a list of \a Clauses.
+ /// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
@@ -3089,7 +3113,7 @@ public:
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
- /// \brief Creates an empty directive with the place
+ /// Creates an empty directive with the place
/// for \a NumClauses clauses.
///
/// \param C AST context.
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
index 98fa113274069..30bc257c7e795 100644
--- a/include/clang/AST/StmtVisitor.h
+++ b/include/clang/AST/StmtVisitor.h
@@ -195,7 +195,7 @@ template<typename ImplClass, typename RetTy=void, typename... ParamTys>
class ConstStmtVisitor
: public StmtVisitorBase<make_const_ptr, ImplClass, RetTy, ParamTys...> {};
-/// \brief This class implements a simple visitor for OMPClause
+/// This class implements a simple visitor for OMPClause
/// subclasses.
template<class ImplClass, template <typename> class Ptr, typename RetTy>
class OMPClauseVisitorBase {
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 850250b9c0a21..a1920253de78a 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -47,12 +47,12 @@ struct PrintingPolicy;
class TypeSourceInfo;
class ValueDecl;
-/// \brief Represents a template argument.
+/// Represents a template argument.
class TemplateArgument {
public:
- /// \brief The kind of template argument we're storing.
+ /// The kind of template argument we're storing.
enum ArgKind {
- /// \brief Represents an empty template argument, e.g., one that has not
+ /// Represents an empty template argument, e.g., one that has not
/// been deduced.
Null = 0,
@@ -92,7 +92,7 @@ public:
};
private:
- /// \brief The kind of template argument we're storing.
+ /// The kind of template argument we're storing.
struct DA {
unsigned Kind;
@@ -138,16 +138,16 @@ private:
};
public:
- /// \brief Construct an empty, invalid template argument.
+ /// Construct an empty, invalid template argument.
constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
- /// \brief Construct a template type argument.
+ /// Construct a template type argument.
TemplateArgument(QualType T, bool isNullPtr = false) {
TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
}
- /// \brief Construct a template argument that refers to a
+ /// Construct a template argument that refers to a
/// declaration, which is either an external declaration or a
/// template declaration.
TemplateArgument(ValueDecl *D, QualType QT) {
@@ -157,18 +157,18 @@ public:
DeclArg.D = D;
}
- /// \brief Construct an integral constant template argument. The memory to
+ /// Construct an integral constant template argument. The memory to
/// store the value is allocated with Ctx.
TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
- /// \brief Construct an integral constant template argument with the same
+ /// Construct an integral constant template argument with the same
/// value as Other but a different type.
TemplateArgument(const TemplateArgument &Other, QualType Type) {
Integer = Other.Integer;
Integer.Type = Type.getAsOpaquePtr();
}
- /// \brief Construct a template argument that is a template.
+ /// Construct a template argument that is a template.
///
/// This form of template argument is generally used for template template
/// parameters. However, the template name could be a dependent template
@@ -182,7 +182,7 @@ public:
TemplateArg.NumExpansions = 0;
}
- /// \brief Construct a template argument that is a template pack expansion.
+ /// Construct a template argument that is a template pack expansion.
///
/// This form of template argument is generally used for template template
/// parameters. However, the template name could be a dependent template
@@ -202,7 +202,7 @@ public:
TemplateArg.NumExpansions = 0;
}
- /// \brief Construct a template argument that is an expression.
+ /// Construct a template argument that is an expression.
///
/// This form of template argument only occurs in template argument
/// lists used for dependent types and for expression; it will not
@@ -212,7 +212,7 @@ public:
TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
}
- /// \brief Construct a template argument that is a template argument pack.
+ /// Construct a template argument that is a template argument pack.
///
/// We assume that storage for the template arguments provided
/// outlives the TemplateArgument itself.
@@ -226,40 +226,40 @@ public:
static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
- /// \brief Create a new template argument pack by copying the given set of
+ /// Create a new template argument pack by copying the given set of
/// template arguments.
static TemplateArgument CreatePackCopy(ASTContext &Context,
ArrayRef<TemplateArgument> Args);
- /// \brief Return the kind of stored template argument.
+ /// Return the kind of stored template argument.
ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
- /// \brief Determine whether this template argument has no value.
+ /// Determine whether this template argument has no value.
bool isNull() const { return getKind() == Null; }
- /// \brief Whether this template argument is dependent on a template
+ /// Whether this template argument is dependent on a template
/// parameter such that its result can change from one instantiation to
/// another.
bool isDependent() const;
- /// \brief Whether this template argument is dependent on a template
+ /// Whether this template argument is dependent on a template
/// parameter.
bool isInstantiationDependent() const;
- /// \brief Whether this template argument contains an unexpanded
+ /// Whether this template argument contains an unexpanded
/// parameter pack.
bool containsUnexpandedParameterPack() const;
- /// \brief Determine whether this template argument is a pack expansion.
+ /// Determine whether this template argument is a pack expansion.
bool isPackExpansion() const;
- /// \brief Retrieve the type for a type template argument.
+ /// Retrieve the type for a type template argument.
QualType getAsType() const {
assert(getKind() == Type && "Unexpected kind");
return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
}
- /// \brief Retrieve the declaration for a declaration non-type
+ /// Retrieve the declaration for a declaration non-type
/// template argument.
ValueDecl *getAsDecl() const {
assert(getKind() == Declaration && "Unexpected kind");
@@ -271,19 +271,19 @@ public:
return QualType::getFromOpaquePtr(DeclArg.QT);
}
- /// \brief Retrieve the type for null non-type template argument.
+ /// Retrieve the type for null non-type template argument.
QualType getNullPtrType() const {
assert(getKind() == NullPtr && "Unexpected kind");
return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
}
- /// \brief Retrieve the template name for a template name argument.
+ /// Retrieve the template name for a template name argument.
TemplateName getAsTemplate() const {
assert(getKind() == Template && "Unexpected kind");
return TemplateName::getFromVoidPointer(TemplateArg.Name);
}
- /// \brief Retrieve the template argument as a template name; if the argument
+ /// Retrieve the template argument as a template name; if the argument
/// is a pack expansion, return the pattern as a template name.
TemplateName getAsTemplateOrTemplatePattern() const {
assert((getKind() == Template || getKind() == TemplateExpansion) &&
@@ -292,11 +292,11 @@ public:
return TemplateName::getFromVoidPointer(TemplateArg.Name);
}
- /// \brief Retrieve the number of expansions that a template template argument
+ /// Retrieve the number of expansions that a template template argument
/// expansion will produce, if known.
Optional<unsigned> getNumTemplateExpansions() const;
- /// \brief Retrieve the template argument as an integral value.
+ /// Retrieve the template argument as an integral value.
// FIXME: Provide a way to read the integral data without copying the value.
llvm::APSInt getAsIntegral() const {
assert(getKind() == Integral && "Unexpected kind");
@@ -311,7 +311,7 @@ public:
Integer.IsUnsigned);
}
- /// \brief Retrieve the type of the integral value.
+ /// Retrieve the type of the integral value.
QualType getIntegralType() const {
assert(getKind() == Integral && "Unexpected kind");
return QualType::getFromOpaquePtr(Integer.Type);
@@ -322,70 +322,70 @@ public:
Integer.Type = T.getAsOpaquePtr();
}
- /// \brief If this is a non-type template argument, get its type. Otherwise,
+ /// If this is a non-type template argument, get its type. Otherwise,
/// returns a null QualType.
QualType getNonTypeTemplateArgumentType() const;
- /// \brief Retrieve the template argument as an expression.
+ /// Retrieve the template argument as an expression.
Expr *getAsExpr() const {
assert(getKind() == Expression && "Unexpected kind");
return reinterpret_cast<Expr *>(TypeOrValue.V);
}
- /// \brief Iterator that traverses the elements of a template argument pack.
+ /// Iterator that traverses the elements of a template argument pack.
using pack_iterator = const TemplateArgument *;
- /// \brief Iterator referencing the first argument of a template argument
+ /// Iterator referencing the first argument of a template argument
/// pack.
pack_iterator pack_begin() const {
assert(getKind() == Pack);
return Args.Args;
}
- /// \brief Iterator referencing one past the last argument of a template
+ /// Iterator referencing one past the last argument of a template
/// argument pack.
pack_iterator pack_end() const {
assert(getKind() == Pack);
return Args.Args + Args.NumArgs;
}
- /// \brief Iterator range referencing all of the elements of a template
+ /// Iterator range referencing all of the elements of a template
/// argument pack.
ArrayRef<TemplateArgument> pack_elements() const {
return llvm::makeArrayRef(pack_begin(), pack_end());
}
- /// \brief The number of template arguments in the given template argument
+ /// The number of template arguments in the given template argument
/// pack.
unsigned pack_size() const {
assert(getKind() == Pack);
return Args.NumArgs;
}
- /// \brief Return the array of arguments in this template argument pack.
+ /// Return the array of arguments in this template argument pack.
ArrayRef<TemplateArgument> getPackAsArray() const {
assert(getKind() == Pack);
return llvm::makeArrayRef(Args.Args, Args.NumArgs);
}
- /// \brief Determines whether two template arguments are superficially the
+ /// Determines whether two template arguments are superficially the
/// same.
bool structurallyEquals(const TemplateArgument &Other) const;
- /// \brief When the template argument is a pack expansion, returns
+ /// When the template argument is a pack expansion, returns
/// the pattern of the pack expansion.
TemplateArgument getPackExpansionPattern() const;
- /// \brief Print this template argument to the given output stream.
+ /// Print this template argument to the given output stream.
void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
- /// \brief Debugging aid that dumps the template argument.
+ /// Debugging aid that dumps the template argument.
void dump(raw_ostream &Out) const;
- /// \brief Debugging aid that dumps the template argument to standard error.
+ /// Debugging aid that dumps the template argument to standard error.
void dump() const;
- /// \brief Used to insert TemplateArguments into FoldingSets.
+ /// Used to insert TemplateArguments into FoldingSets.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
};
@@ -478,7 +478,7 @@ public:
Argument.getKind() == TemplateArgument::TemplateExpansion);
}
- /// \brief - Fetches the primary location of the argument.
+ /// - Fetches the primary location of the argument.
SourceLocation getLocation() const {
if (Argument.getKind() == TemplateArgument::Template ||
Argument.getKind() == TemplateArgument::TemplateExpansion)
@@ -487,7 +487,7 @@ public:
return getSourceRange().getBegin();
}
- /// \brief - Fetches the full source range of the argument.
+ /// - Fetches the full source range of the argument.
SourceRange getSourceRange() const LLVM_READONLY;
const TemplateArgument &getArgument() const {
@@ -588,7 +588,7 @@ public:
}
};
-/// \brief Represents an explicit template argument list in C++, e.g.,
+/// Represents an explicit template argument list in C++, e.g.,
/// the "<int>" in "sort<int>".
/// This is safe to be used inside an AST node, in contrast with
/// TemplateArgumentListInfo.
@@ -602,16 +602,16 @@ private:
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
public:
- /// \brief The source location of the left angle bracket ('<').
+ /// The source location of the left angle bracket ('<').
SourceLocation LAngleLoc;
- /// \brief The source location of the right angle bracket ('>').
+ /// The source location of the right angle bracket ('>').
SourceLocation RAngleLoc;
- /// \brief The number of template arguments in TemplateArgs.
+ /// The number of template arguments in TemplateArgs.
unsigned NumTemplateArgs;
- /// \brief Retrieve the template arguments
+ /// Retrieve the template arguments
const TemplateArgumentLoc *getTemplateArgs() const {
return getTrailingObjects<TemplateArgumentLoc>();
}
@@ -628,7 +628,7 @@ public:
Create(ASTContext &C, const TemplateArgumentListInfo &List);
};
-/// \brief Represents an explicit template argument list in C++, e.g.,
+/// Represents an explicit template argument list in C++, e.g.,
/// the "<int>" in "sort<int>".
///
/// It is intended to be used as a trailing object on AST nodes, and
@@ -636,19 +636,19 @@ public:
/// but expects the containing object to also provide storage for
/// that.
struct alignas(void *) ASTTemplateKWAndArgsInfo {
- /// \brief The source location of the left angle bracket ('<').
+ /// The source location of the left angle bracket ('<').
SourceLocation LAngleLoc;
- /// \brief The source location of the right angle bracket ('>').
+ /// The source location of the right angle bracket ('>').
SourceLocation RAngleLoc;
- /// \brief The source location of the template keyword; this is used
+ /// The source location of the template keyword; this is used
/// as part of the representation of qualified identifiers, such as
/// S<T>::template apply<T>. Will be empty if this expression does
/// not have a template keyword.
SourceLocation TemplateKWLoc;
- /// \brief The number of template arguments in TemplateArgs.
+ /// The number of template arguments in TemplateArgs.
unsigned NumTemplateArgs;
void initializeFrom(SourceLocation TemplateKWLoc,
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index fb33cf58d7960..50549e1a0a6a3 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -39,7 +39,7 @@ class TemplateArgument;
class TemplateDecl;
class TemplateTemplateParmDecl;
-/// \brief Implementation class used to describe either a set of overloaded
+/// Implementation class used to describe either a set of overloaded
/// template names or an already-substituted template template parameter pack.
class UncommonTemplateNameStorage {
protected:
@@ -50,10 +50,10 @@ protected:
};
struct BitsTag {
- /// \brief A Kind.
+ /// A Kind.
unsigned Kind : 2;
- /// \brief The number of stored templates or template arguments,
+ /// The number of stored templates or template arguments,
/// depending on which subclass we have.
unsigned Size : 30;
};
@@ -90,7 +90,7 @@ public:
}
};
-/// \brief A structure for storing the information associated with an
+/// A structure for storing the information associated with an
/// overloaded template name.
class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
friend class ASTContext;
@@ -112,7 +112,7 @@ public:
iterator end() const { return getStorage() + size(); }
};
-/// \brief A structure for storing an already-substituted template template
+/// A structure for storing an already-substituted template template
/// parameter pack.
///
/// This kind of template names occurs when the parameter pack has been
@@ -131,12 +131,12 @@ public:
: UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
Parameter(Parameter), Arguments(Arguments) {}
- /// \brief Retrieve the template template parameter pack being substituted.
+ /// Retrieve the template template parameter pack being substituted.
TemplateTemplateParmDecl *getParameterPack() const {
return Parameter;
}
- /// \brief Retrieve the template template argument pack with which this
+ /// Retrieve the template template argument pack with which this
/// parameter was substituted.
TemplateArgument getArgumentPack() const;
@@ -148,7 +148,7 @@ public:
const TemplateArgument &ArgPack);
};
-/// \brief Represents a C++ template name within the type system.
+/// Represents a C++ template name within the type system.
///
/// A C++ template name refers to a template within the C++ type
/// system. In most cases, a template name is simply a reference to a
@@ -185,27 +185,27 @@ class TemplateName {
explicit TemplateName(void *Ptr);
public:
- // \brief Kind of name that is actually stored.
+ // Kind of name that is actually stored.
enum NameKind {
- /// \brief A single template declaration.
+ /// A single template declaration.
Template,
- /// \brief A set of overloaded template declarations.
+ /// A set of overloaded template declarations.
OverloadedTemplate,
- /// \brief A qualified template name, where the qualification is kept
+ /// A qualified template name, where the qualification is kept
/// to describe the source code as written.
QualifiedTemplate,
- /// \brief A dependent template name that has not been resolved to a
+ /// A dependent template name that has not been resolved to a
/// template (or set of templates).
DependentTemplate,
- /// \brief A template template parameter that has been substituted
+ /// A template template parameter that has been substituted
/// for some other template name.
SubstTemplateTemplateParm,
- /// \brief A template template parameter pack that has been substituted for
+ /// A template template parameter pack that has been substituted for
/// a template template argument pack, but has not yet been expanded into
/// individual arguments.
SubstTemplateTemplateParmPack
@@ -219,13 +219,13 @@ public:
explicit TemplateName(QualifiedTemplateName *Qual);
explicit TemplateName(DependentTemplateName *Dep);
- /// \brief Determine whether this template name is NULL.
+ /// Determine whether this template name is NULL.
bool isNull() const;
- // \brief Get the kind of name that is actually stored.
+ // Get the kind of name that is actually stored.
NameKind getKind() const;
- /// \brief Retrieve the underlying template declaration that
+ /// Retrieve the underlying template declaration that
/// this template name refers to, if known.
///
/// \returns The template declaration that this template name refers
@@ -234,7 +234,7 @@ public:
/// set of function templates, returns NULL.
TemplateDecl *getAsTemplateDecl() const;
- /// \brief Retrieve the underlying, overloaded function template
+ /// Retrieve the underlying, overloaded function template
// declarations that this template name refers to, if known.
///
/// \returns The set of overloaded function templates that this template
@@ -243,14 +243,14 @@ public:
/// refers to a single template, returns NULL.
OverloadedTemplateStorage *getAsOverloadedTemplate() const;
- /// \brief Retrieve the substituted template template parameter, if
+ /// Retrieve the substituted template template parameter, if
/// known.
///
/// \returns The storage for the substituted template template parameter,
/// if known. Otherwise, returns NULL.
SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const;
- /// \brief Retrieve the substituted template template parameter pack, if
+ /// Retrieve the substituted template template parameter pack, if
/// known.
///
/// \returns The storage for the substituted template template parameter pack,
@@ -258,11 +258,11 @@ public:
SubstTemplateTemplateParmPackStorage *
getAsSubstTemplateTemplateParmPack() const;
- /// \brief Retrieve the underlying qualified template name
+ /// Retrieve the underlying qualified template name
/// structure, if any.
QualifiedTemplateName *getAsQualifiedTemplateName() const;
- /// \brief Retrieve the underlying dependent template name
+ /// Retrieve the underlying dependent template name
/// structure, if any.
DependentTemplateName *getAsDependentTemplateName() const;
@@ -273,18 +273,18 @@ public:
/// the template, including any default template arguments.
TemplateName getNameToSubstitute() const;
- /// \brief Determines whether this is a dependent template name.
+ /// Determines whether this is a dependent template name.
bool isDependent() const;
- /// \brief Determines whether this is a template name that somehow
+ /// Determines whether this is a template name that somehow
/// depends on a template parameter.
bool isInstantiationDependent() const;
- /// \brief Determines whether this template name contains an
+ /// Determines whether this template name contains an
/// unexpanded parameter pack (for C++0x variadic templates).
bool containsUnexpandedParameterPack() const;
- /// \brief Print the template name.
+ /// Print the template name.
///
/// \param OS the output stream to which the template name will be
/// printed.
@@ -295,10 +295,10 @@ public:
void print(raw_ostream &OS, const PrintingPolicy &Policy,
bool SuppressNNS = false) const;
- /// \brief Debugging aid that dumps the template name.
+ /// Debugging aid that dumps the template name.
void dump(raw_ostream &OS) const;
- /// \brief Debugging aid that dumps the template name to standard
+ /// Debugging aid that dumps the template name to standard
/// error.
void dump() const;
@@ -306,10 +306,10 @@ public:
ID.AddPointer(Storage.getOpaqueValue());
}
- /// \brief Retrieve the template name as a void pointer.
+ /// Retrieve the template name as a void pointer.
void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
- /// \brief Build a template name from a void pointer.
+ /// Build a template name from a void pointer.
static TemplateName getFromVoidPointer(void *Ptr) {
return TemplateName(Ptr);
}
@@ -320,7 +320,7 @@ public:
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
TemplateName N);
-/// \brief A structure for storing the information associated with a
+/// A structure for storing the information associated with a
/// substituted template template parameter.
class SubstTemplateTemplateParmStorage
: public UncommonTemplateNameStorage, public llvm::FoldingSetNode {
@@ -352,7 +352,7 @@ inline TemplateName TemplateName::getUnderlying() const {
return *this;
}
-/// \brief Represents a template name that was expressed as a
+/// Represents a template name that was expressed as a
/// qualified name.
///
/// This kind of template name refers to a template name that was
@@ -366,7 +366,7 @@ inline TemplateName TemplateName::getUnderlying() const {
class QualifiedTemplateName : public llvm::FoldingSetNode {
friend class ASTContext;
- /// \brief The nested name specifier that qualifies the template name.
+ /// The nested name specifier that qualifies the template name.
///
/// The bit is used to indicate whether the "template" keyword was
/// present before the template name itself. Note that the
@@ -375,7 +375,7 @@ class QualifiedTemplateName : public llvm::FoldingSetNode {
/// this name with DependentTemplateName).
llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
- /// \brief The template declaration or set of overloaded function templates
+ /// The template declaration or set of overloaded function templates
/// that this qualified name refers to.
TemplateDecl *Template;
@@ -384,18 +384,18 @@ class QualifiedTemplateName : public llvm::FoldingSetNode {
: Qualifier(NNS, TemplateKeyword? 1 : 0), Template(Template) {}
public:
- /// \brief Return the nested name specifier that qualifies this name.
+ /// Return the nested name specifier that qualifies this name.
NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
- /// \brief Whether the template name was prefixed by the "template"
+ /// Whether the template name was prefixed by the "template"
/// keyword.
bool hasTemplateKeyword() const { return Qualifier.getInt(); }
- /// \brief The template declaration that this qualified name refers
+ /// The template declaration that this qualified name refers
/// to.
TemplateDecl *getDecl() const { return Template; }
- /// \brief The template declaration to which this qualified name
+ /// The template declaration to which this qualified name
/// refers.
TemplateDecl *getTemplateDecl() const { return Template; }
@@ -411,7 +411,7 @@ public:
}
};
-/// \brief Represents a dependent template name that cannot be
+/// Represents a dependent template name that cannot be
/// resolved prior to template instantiation.
///
/// This kind of template name refers to a dependent template name,
@@ -422,7 +422,7 @@ public:
class DependentTemplateName : public llvm::FoldingSetNode {
friend class ASTContext;
- /// \brief The nested name specifier that qualifies the template
+ /// The nested name specifier that qualifies the template
/// name.
///
/// The bit stored in this qualifier describes whether the \c Name field
@@ -430,20 +430,20 @@ class DependentTemplateName : public llvm::FoldingSetNode {
/// overloaded operator kind (when set).
llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier;
- /// \brief The dependent template name.
+ /// The dependent template name.
union {
- /// \brief The identifier template name.
+ /// The identifier template name.
///
/// Only valid when the bit on \c Qualifier is clear.
const IdentifierInfo *Identifier;
- /// \brief The overloaded operator name.
+ /// The overloaded operator name.
///
/// Only valid when the bit on \c Qualifier is set.
OverloadedOperatorKind Operator;
};
- /// \brief The canonical template name to which this dependent
+ /// The canonical template name to which this dependent
/// template name refers.
///
/// The canonical template name for a dependent template name is
@@ -474,23 +474,23 @@ class DependentTemplateName : public llvm::FoldingSetNode {
CanonicalTemplateName(Canon) {}
public:
- /// \brief Return the nested name specifier that qualifies this name.
+ /// Return the nested name specifier that qualifies this name.
NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
- /// \brief Determine whether this template name refers to an identifier.
+ /// Determine whether this template name refers to an identifier.
bool isIdentifier() const { return !Qualifier.getInt(); }
- /// \brief Returns the identifier to which this template name refers.
+ /// Returns the identifier to which this template name refers.
const IdentifierInfo *getIdentifier() const {
assert(isIdentifier() && "Template name isn't an identifier?");
return Identifier;
}
- /// \brief Determine whether this template name refers to an overloaded
+ /// Determine whether this template name refers to an overloaded
/// operator.
bool isOverloadedOperator() const { return Qualifier.getInt(); }
- /// \brief Return the overloaded operator to which this template name refers.
+ /// Return the overloaded operator to which this template name refers.
OverloadedOperatorKind getOperator() const {
assert(isOverloadedOperator() &&
"Template name isn't an overloaded operator?");
@@ -523,7 +523,7 @@ public:
namespace llvm {
-/// \brief The clang::TemplateName class is effectively a pointer.
+/// The clang::TemplateName class is effectively a pointer.
template<>
struct PointerLikeTypeTraits<clang::TemplateName> {
static inline void *getAsVoidPointer(clang::TemplateName TN) {
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 882878bb7e1e7..c692707847a69 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief C Language Family Type Representation
+/// C Language Family Type Representation
///
/// This file defines the clang::Type interface and subclasses, used to
/// represent types for languages in the C family.
@@ -30,6 +30,7 @@
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/Visibility.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/None.h"
@@ -56,6 +57,7 @@ namespace clang {
class ExtQuals;
class QualType;
+class TagDecl;
class Type;
enum {
@@ -445,7 +447,7 @@ public:
}
}
- /// \brief Remove the qualifiers from the given set from this set.
+ /// Remove the qualifiers from the given set from this set.
void removeQualifiers(Qualifiers Q) {
// If the other set doesn't have any non-boolean qualifiers, just
// bit-and the inverse in.
@@ -508,7 +510,7 @@ public:
(!other.hasUnaligned() || hasUnaligned());
}
- /// \brief Determines if these qualifiers compatibly include another set of
+ /// Determines if these qualifiers compatibly include another set of
/// qualifiers from the narrow perspective of Objective-C ARC lifetime.
///
/// One set of Objective-C lifetime qualifiers compatibly includes the other
@@ -528,7 +530,7 @@ public:
return hasConst();
}
- /// \brief Determine whether this set of qualifiers is a strict superset of
+ /// Determine whether this set of qualifiers is a strict superset of
/// another set of qualifiers, not considering qualifier compatibility.
bool isStrictSupersetOf(Qualifiers Other) const;
@@ -554,7 +556,7 @@ public:
return *this;
}
- /// \brief Compute the difference between two qualifier sets.
+ /// Compute the difference between two qualifier sets.
friend Qualifiers operator-(Qualifiers L, Qualifiers R) {
L -= R;
return L;
@@ -667,8 +669,7 @@ class QualType {
const ExtQualsTypeCommonBase *getCommonPtr() const {
assert(!isNull() && "Cannot retrieve a NULL type pointer");
- uintptr_t CommonPtrVal
- = reinterpret_cast<uintptr_t>(Value.getOpaqueValue());
+ auto CommonPtrVal = reinterpret_cast<uintptr_t>(Value.getOpaqueValue());
CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1);
return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal);
}
@@ -720,69 +721,69 @@ public:
return Value.getPointer().isNull();
}
- /// \brief Determine whether this particular QualType instance has the
+ /// Determine whether this particular QualType instance has the
/// "const" qualifier set, without looking through typedefs that may have
/// added "const" at a different level.
bool isLocalConstQualified() const {
return (getLocalFastQualifiers() & Qualifiers::Const);
}
- /// \brief Determine whether this type is const-qualified.
+ /// Determine whether this type is const-qualified.
bool isConstQualified() const;
- /// \brief Determine whether this particular QualType instance has the
+ /// Determine whether this particular QualType instance has the
/// "restrict" qualifier set, without looking through typedefs that may have
/// added "restrict" at a different level.
bool isLocalRestrictQualified() const {
return (getLocalFastQualifiers() & Qualifiers::Restrict);
}
- /// \brief Determine whether this type is restrict-qualified.
+ /// Determine whether this type is restrict-qualified.
bool isRestrictQualified() const;
- /// \brief Determine whether this particular QualType instance has the
+ /// Determine whether this particular QualType instance has the
/// "volatile" qualifier set, without looking through typedefs that may have
/// added "volatile" at a different level.
bool isLocalVolatileQualified() const {
return (getLocalFastQualifiers() & Qualifiers::Volatile);
}
- /// \brief Determine whether this type is volatile-qualified.
+ /// Determine whether this type is volatile-qualified.
bool isVolatileQualified() const;
- /// \brief Determine whether this particular QualType instance has any
+ /// Determine whether this particular QualType instance has any
/// qualifiers, without looking through any typedefs that might add
/// qualifiers at a different level.
bool hasLocalQualifiers() const {
return getLocalFastQualifiers() || hasLocalNonFastQualifiers();
}
- /// \brief Determine whether this type has any qualifiers.
+ /// Determine whether this type has any qualifiers.
bool hasQualifiers() const;
- /// \brief Determine whether this particular QualType instance has any
+ /// Determine whether this particular QualType instance has any
/// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
/// instance.
bool hasLocalNonFastQualifiers() const {
return Value.getPointer().is<const ExtQuals*>();
}
- /// \brief Retrieve the set of qualifiers local to this particular QualType
+ /// Retrieve the set of qualifiers local to this particular QualType
/// instance, not including any qualifiers acquired through typedefs or
/// other sugar.
Qualifiers getLocalQualifiers() const;
- /// \brief Retrieve the set of qualifiers applied to this type.
+ /// Retrieve the set of qualifiers applied to this type.
Qualifiers getQualifiers() const;
- /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+ /// Retrieve the set of CVR (const-volatile-restrict) qualifiers
/// local to this particular QualType instance, not including any qualifiers
/// acquired through typedefs or other sugar.
unsigned getLocalCVRQualifiers() const {
return getLocalFastQualifiers();
}
- /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+ /// Retrieve the set of CVR (const-volatile-restrict) qualifiers
/// applied to this type.
unsigned getCVRQualifiers() const;
@@ -790,7 +791,7 @@ public:
return QualType::isConstant(*this, Ctx);
}
- /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
+ /// Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
bool isPODType(const ASTContext &Context) const;
/// Return true if this is a POD type according to the rules of the C++98
@@ -799,7 +800,8 @@ public:
/// Return true if this is a POD type according to the more relaxed rules
/// of the C++11 standard, regardless of the current compilation's language.
- /// (C++0x [basic.types]p9)
+ /// (C++0x [basic.types]p9). Note that, unlike
+ /// CXXRecordDecl::isCXX11StandardLayout, this takes DRs into account.
bool isCXX11PODType(const ASTContext &Context) const;
/// Return true if this is a trivial type per (C++0x [basic.types]p9)
@@ -808,6 +810,13 @@ public:
/// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
bool isTriviallyCopyableType(const ASTContext &Context) const;
+
+ /// Returns true if it is a class and it might be dynamic.
+ bool mayBeDynamicClass() const;
+
+ /// Returns true if it is not a class or if the class might not be dynamic.
+ bool mayBeNotDynamicClass() const;
+
// Don't promise in the API that anything besides 'const' can be
// easily added.
@@ -879,12 +888,12 @@ public:
QualType getCanonicalType() const;
- /// \brief Return this type with all of the instance-specific qualifiers
+ /// Return this type with all of the instance-specific qualifiers
/// removed, but without removing any qualifiers that may have been applied
/// through typedefs.
QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); }
- /// \brief Retrieve the unqualified variant of the given type,
+ /// Retrieve the unqualified variant of the given type,
/// removing as little sugar as possible.
///
/// This routine looks through various kinds of sugar to find the
@@ -915,17 +924,17 @@ public:
/// ASTContext::getUnqualifiedArrayType.
inline SplitQualType getSplitUnqualifiedType() const;
- /// \brief Determine whether this type is more qualified than the other
+ /// Determine whether this type is more qualified than the other
/// given type, requiring exact equality for non-CVR qualifiers.
bool isMoreQualifiedThan(QualType Other) const;
- /// \brief Determine whether this type is at least as qualified as the other
+ /// Determine whether this type is at least as qualified as the other
/// given type, requiring exact equality for non-CVR qualifiers.
bool isAtLeastAsQualifiedAs(QualType Other) const;
QualType getNonReferenceType() const;
- /// \brief Determine the type of a (typically non-lvalue) expression with the
+ /// Determine the type of a (typically non-lvalue) expression with the
/// specified result type.
///
/// This routine should be used for expressions for which the return type is
@@ -951,7 +960,7 @@ public:
return getSplitDesugaredType(*this);
}
- /// \brief Return the specified type with one level of "sugar" removed from
+ /// Return the specified type with one level of "sugar" removed from
/// the type.
///
/// This routine takes off the first typedef, typeof, etc. If the outer level
@@ -1082,11 +1091,79 @@ public:
// true when Type is objc's weak and weak is enabled but ARC isn't.
bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const;
+ enum PrimitiveDefaultInitializeKind {
+ /// The type does not fall into any of the following categories. Note that
+ /// this case is zero-valued so that values of this enum can be used as a
+ /// boolean condition for non-triviality.
+ PDIK_Trivial,
+
+ /// The type is an Objective-C retainable pointer type that is qualified
+ /// with the ARC __strong qualifier.
+ PDIK_ARCStrong,
+
+ /// The type is an Objective-C retainable pointer type that is qualified
+ /// with the ARC __weak qualifier.
+ PDIK_ARCWeak,
+
+ /// The type is a struct containing a field whose type is not PCK_Trivial.
+ PDIK_Struct
+ };
+
+ /// Functions to query basic properties of non-trivial C struct types.
+
+ /// Check if this is a non-trivial type that would cause a C struct
+ /// transitively containing this type to be non-trivial to default initialize
+ /// and return the kind.
+ PrimitiveDefaultInitializeKind
+ isNonTrivialToPrimitiveDefaultInitialize() const;
+
+ enum PrimitiveCopyKind {
+ /// The type does not fall into any of the following categories. Note that
+ /// this case is zero-valued so that values of this enum can be used as a
+ /// boolean condition for non-triviality.
+ PCK_Trivial,
+
+ /// The type would be trivial except that it is volatile-qualified. Types
+ /// that fall into one of the other non-trivial cases may additionally be
+ /// volatile-qualified.
+ PCK_VolatileTrivial,
+
+ /// The type is an Objective-C retainable pointer type that is qualified
+ /// with the ARC __strong qualifier.
+ PCK_ARCStrong,
+
+ /// The type is an Objective-C retainable pointer type that is qualified
+ /// with the ARC __weak qualifier.
+ PCK_ARCWeak,
+
+ /// The type is a struct containing a field whose type is neither
+ /// PCK_Trivial nor PCK_VolatileTrivial.
+ /// Note that a C++ struct type does not necessarily match this; C++ copying
+ /// semantics are too complex to express here, in part because they depend
+ /// on the exact constructor or assignment operator that is chosen by
+ /// overload resolution to do the copy.
+ PCK_Struct
+ };
+
+ /// Check if this is a non-trivial type that would cause a C struct
+ /// transitively containing this type to be non-trivial to copy and return the
+ /// kind.
+ PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const;
+
+ /// Check if this is a non-trivial type that would cause a C struct
+ /// transitively containing this type to be non-trivial to destructively
+ /// move and return the kind. Destructive move in this context is a C++-style
+ /// move in which the source object is placed in a valid but unspecified state
+ /// after it is moved, as opposed to a truly destructive move in which the
+ /// source object is placed in an uninitialized state.
+ PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const;
+
enum DestructionKind {
DK_none,
DK_cxx_destructor,
DK_objc_strong_lifetime,
- DK_objc_weak_lifetime
+ DK_objc_weak_lifetime,
+ DK_nontrivial_c_struct
};
/// Returns a nonzero value if objects of this type require
@@ -1204,7 +1281,7 @@ struct PointerLikeTypeTraits<clang::QualType> {
namespace clang {
-/// \brief Base class that is common to both the \c ExtQuals and \c Type
+/// Base class that is common to both the \c ExtQuals and \c Type
/// classes, which allows \c QualType to access the common fields between the
/// two.
class ExtQualsTypeCommonBase {
@@ -1212,14 +1289,14 @@ class ExtQualsTypeCommonBase {
friend class QualType;
friend class Type;
- /// \brief The "base" type of an extended qualifiers type (\c ExtQuals) or
+ /// The "base" type of an extended qualifiers type (\c ExtQuals) or
/// a self-referential pointer (for \c Type).
///
/// This pointer allows an efficient mapping from a QualType to its
/// underlying type pointer.
const Type *const BaseType;
- /// \brief The canonical type of this type. A QualType.
+ /// The canonical type of this type. A QualType.
QualType CanonicalType;
ExtQualsTypeCommonBase(const Type *baseType, QualType canon)
@@ -1300,25 +1377,25 @@ public:
/// This determines whether a member function's "this" object can be an
/// lvalue, rvalue, or neither.
enum RefQualifierKind {
- /// \brief No ref-qualifier was provided.
+ /// No ref-qualifier was provided.
RQ_None = 0,
- /// \brief An lvalue ref-qualifier was provided (\c &).
+ /// An lvalue ref-qualifier was provided (\c &).
RQ_LValue,
- /// \brief An rvalue ref-qualifier was provided (\c &&).
+ /// An rvalue ref-qualifier was provided (\c &&).
RQ_RValue
};
/// Which keyword(s) were used to create an AutoType.
enum class AutoTypeKeyword {
- /// \brief auto
+ /// auto
Auto,
- /// \brief decltype(auto)
+ /// decltype(auto)
DecltypeAuto,
- /// \brief __auto_type (GNU extension)
+ /// __auto_type (GNU extension)
GNUAutoType
};
@@ -1377,21 +1454,21 @@ private:
/// Whether this type is a variably-modified type (C99 6.7.5).
unsigned VariablyModified : 1;
- /// \brief Whether this type contains an unexpanded parameter pack
+ /// Whether this type contains an unexpanded parameter pack
/// (for C++11 variadic templates).
unsigned ContainsUnexpandedParameterPack : 1;
- /// \brief True if the cache (i.e. the bitfields here starting with
+ /// True if the cache (i.e. the bitfields here starting with
/// 'Cache') is valid.
mutable unsigned CacheValid : 1;
- /// \brief Linkage of this type.
+ /// Linkage of this type.
mutable unsigned CachedLinkage : 3;
- /// \brief Whether this type involves and local or unnamed types.
+ /// Whether this type involves and local or unnamed types.
mutable unsigned CachedLocalOrUnnamed : 1;
- /// \brief Whether this type comes from an AST file.
+ /// Whether this type comes from an AST file.
mutable unsigned FromAST : 1;
bool isCacheValid() const {
@@ -1446,7 +1523,7 @@ protected:
/// Extra information which affects how the function is called, like
/// regparm and the calling convention.
- unsigned ExtInfo : 11;
+ unsigned ExtInfo : 12;
/// Used only by FunctionProtoType, put here to pack with the
/// other bitfields.
@@ -1456,7 +1533,7 @@ protected:
/// cv-qualifier-seq, [...], are part of the function type.
unsigned TypeQuals : 4;
- /// \brief The ref-qualifier associated with a \c FunctionProtoType.
+ /// The ref-qualifier associated with a \c FunctionProtoType.
///
/// This is a value of type \c RefQualifierKind.
unsigned RefQualifier : 2;
@@ -1513,6 +1590,7 @@ protected:
class VectorTypeBitfields {
friend class VectorType;
+ friend class DependentVectorType;
unsigned : NumTypeBits;
@@ -1561,7 +1639,7 @@ protected:
private:
template <class T> friend class TypePropertyCache;
- /// \brief Set whether this type comes from an AST file.
+ /// Set whether this type comes from an AST file.
void setFromAST(bool V = true) const {
TypeBits.FromAST = V;
}
@@ -1612,10 +1690,10 @@ public:
TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); }
- /// \brief Whether this type comes from an AST file.
+ /// Whether this type comes from an AST file.
bool isFromAST() const { return TypeBits.FromAST; }
- /// \brief Whether this type is or contains an unexpanded parameter
+ /// Whether this type is or contains an unexpanded parameter
/// pack, used to support C++0x variadic templates.
///
/// A type that contains a parameter pack shall be expanded by the
@@ -1653,7 +1731,7 @@ public:
/// determine its size (e.g. void, or a fwd declared struct). Clients of this
/// routine will need to determine if the size is actually required.
///
- /// \brief Def If non-null, and the type refers to some kind of declaration
+ /// Def If non-null, and the type refers to some kind of declaration
/// that can be completed (such as a C struct, C++ class, or Objective-C
/// class), will be set to the declaration.
bool isIncompleteType(NamedDecl **Def = nullptr) const;
@@ -1664,7 +1742,7 @@ public:
return !isFunctionType();
}
- /// \brief Determine whether this type is an object type.
+ /// Determine whether this type is an object type.
bool isObjectType() const {
// C++ [basic.types]p8:
// An object type is a (possibly cv-qualified) type that is not a
@@ -1706,9 +1784,13 @@ public:
/// isComplexIntegerType() can be used to test for complex integers.
bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum)
bool isEnumeralType() const;
+
+ /// Determine whether this type is a scoped enumeration type.
+ bool isScopedEnumeralType() const;
bool isBooleanType() const;
bool isCharType() const;
bool isWideCharType() const;
+ bool isChar8Type() const;
bool isChar16Type() const;
bool isChar32Type() const;
bool isAnyCharacterType() const;
@@ -1728,6 +1810,8 @@ public:
bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int.
bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex)
bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half)
+ bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661
+ bool isFloat128Type() const;
bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
bool isVoidType() const; // C99 6.2.5p19
@@ -1857,7 +1941,7 @@ public:
/// somehow depends on a template parameter (C++ [temp.dep.type]).
bool isDependentType() const { return TypeBits.Dependent; }
- /// \brief Determine whether this type is an instantiation-dependent type,
+ /// Determine whether this type is an instantiation-dependent type,
/// meaning that the type involves a template parameter (even if the
/// definition does not actually depend on the type substituted for that
/// template parameter).
@@ -1865,24 +1949,24 @@ public:
return TypeBits.InstantiationDependent;
}
- /// \brief Determine whether this type is an undeduced type, meaning that
+ /// Determine whether this type is an undeduced type, meaning that
/// it somehow involves a C++11 'auto' type or similar which has not yet been
/// deduced.
bool isUndeducedType() const;
- /// \brief Whether this type is a variably-modified type (C99 6.7.5).
+ /// Whether this type is a variably-modified type (C99 6.7.5).
bool isVariablyModifiedType() const { return TypeBits.VariablyModified; }
- /// \brief Whether this type involves a variable-length array type
+ /// Whether this type involves a variable-length array type
/// with a definite size.
bool hasSizedVLAType() const;
- /// \brief Whether this type is or contains a local or unnamed type.
+ /// Whether this type is or contains a local or unnamed type.
bool hasUnnamedOrLocalType() const;
bool isOverloadableType() const;
- /// \brief Determine wither this type is a C++ elaborated-type-specifier.
+ /// Determine wither this type is a C++ elaborated-type-specifier.
bool isElaboratedTypeSpecifier() const;
bool canDecayToPointerType() const;
@@ -1896,19 +1980,19 @@ public:
/// purpose of GC'ability
bool hasObjCPointerRepresentation() const;
- /// \brief Determine whether this type has an integer representation
+ /// Determine whether this type has an integer representation
/// of some sort, e.g., it is an integer type or a vector.
bool hasIntegerRepresentation() const;
- /// \brief Determine whether this type has an signed integer representation
+ /// Determine whether this type has an signed integer representation
/// of some sort, e.g., it is an signed integer type or a vector.
bool hasSignedIntegerRepresentation() const;
- /// \brief Determine whether this type has an unsigned integer representation
+ /// Determine whether this type has an unsigned integer representation
/// of some sort, e.g., it is an unsigned integer type or a vector.
bool hasUnsignedIntegerRepresentation() const;
- /// \brief Determine whether this type has a floating-point representation
+ /// Determine whether this type has a floating-point representation
/// of some sort, e.g., it is a floating-point type or a vector thereof.
bool hasFloatingRepresentation() const;
@@ -1928,18 +2012,18 @@ public:
const ObjCObjectPointerType *getAsObjCQualifiedClassType() const;
const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
- /// \brief Retrieves the CXXRecordDecl that this type refers to, either
+ /// Retrieves the CXXRecordDecl that this type refers to, either
/// because the type is a RecordType or because it is the injected-class-name
/// type of a class template or class template partial specialization.
CXXRecordDecl *getAsCXXRecordDecl() const;
- /// \brief Retrieves the TagDecl that this type refers to, either
+ /// Retrieves the TagDecl that this type refers to, either
/// because the type is a TagType or because it is the injected-class-name
/// type of a class template or class template partial specialization.
TagDecl *getAsTagDecl() const;
/// If this is a pointer or reference to a RecordType, return the
- /// CXXRecordDecl that that type refers to.
+ /// CXXRecordDecl that the type refers to.
///
/// If this is not a pointer or reference, or the type being pointed to does
/// not refer to a CXXRecordDecl, returns NULL.
@@ -2037,6 +2121,26 @@ public:
/// enumeration types whose underlying type is a unsigned integer type.
bool isUnsignedIntegerOrEnumerationType() const;
+ /// Return true if this is a fixed point type according to
+ /// ISO/IEC JTC1 SC22 WG14 N1169.
+ bool isFixedPointType() const;
+
+ /// Return true if this is a saturated fixed point type according to
+ /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned.
+ bool isSaturatedFixedPointType() const;
+
+ /// Return true if this is a saturated fixed point type according to
+ /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned.
+ bool isUnsaturatedFixedPointType() const;
+
+ /// Return true if this is a fixed point type that is signed according
+ /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated.
+ bool isSignedFixedPointType() const;
+
+ /// Return true if this is a fixed point type that is unsigned according
+ /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated.
+ bool isUnsignedFixedPointType() const;
+
/// Return true if this is not a variable sized type,
/// according to the rules of C99 6.7.5p3. It is not legal to call this on
/// incomplete types.
@@ -2113,16 +2217,16 @@ public:
void dump(llvm::raw_ostream &OS) const;
};
-/// \brief This will check for a TypedefType by removing any existing sugar
+/// This will check for a TypedefType by removing any existing sugar
/// until it reaches a TypedefType or a non-sugared type.
template <> const TypedefType *Type::getAs() const;
-/// \brief This will check for a TemplateSpecializationType by removing any
+/// This will check for a TemplateSpecializationType by removing any
/// existing sugar until it reaches a TemplateSpecializationType or a
/// non-sugared type.
template <> const TemplateSpecializationType *Type::getAs() const;
-/// \brief This will check for an AttributedType by removing any existing sugar
+/// This will check for an AttributedType by removing any existing sugar
/// until it reaches an AttributedType or a non-sugared type.
template <> const AttributedType *Type::getAs() const;
@@ -2152,7 +2256,9 @@ public:
#include "clang/AST/BuiltinTypes.def"
};
-public:
+private:
+ friend class ASTContext; // ASTContext creates these.
+
BuiltinType(Kind K)
: Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
/*InstantiationDependent=*/(K == Dependent),
@@ -2161,6 +2267,7 @@ public:
BuiltinTypeBits.Kind = K;
}
+public:
Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); }
StringRef getName(const PrintingPolicy &Policy) const;
@@ -2637,13 +2744,13 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- /// \brief Determine the number of bits required to address a member of
+ /// Determine the number of bits required to address a member of
// an array with the given element type and number of elements.
static unsigned getNumAddressingBits(const ASTContext &Context,
QualType ElementType,
const llvm::APInt &NumElements);
- /// \brief Determine the maximum number of active bits that an array's size
+ /// Determine the maximum number of active bits that an array's size
/// can require, which limits the maximum size of the array.
static unsigned getMaxSizeBits(const ASTContext &Context);
@@ -2774,7 +2881,7 @@ class DependentSizedArrayType : public ArrayType {
const ASTContext &Context;
- /// \brief An assignment expression that will instantiate to the
+ /// An assignment expression that will instantiate to the
/// size of the array.
///
/// The expression itself might be null, in which case the array
@@ -2979,6 +3086,51 @@ public:
}
};
+/// Represents a vector type where either the type or size is dependent.
+////
+/// For example:
+/// \code
+/// template<typename T, int Size>
+/// class vector {
+/// typedef T __attribute__((vector_size(Size))) type;
+/// }
+/// \endcode
+class DependentVectorType : public Type, public llvm::FoldingSetNode {
+ friend class ASTContext;
+
+ const ASTContext &Context;
+ QualType ElementType;
+ Expr *SizeExpr;
+ SourceLocation Loc;
+
+ DependentVectorType(const ASTContext &Context, QualType ElementType,
+ QualType CanonType, Expr *SizeExpr,
+ SourceLocation Loc, VectorType::VectorKind vecKind);
+
+public:
+ Expr *getSizeExpr() const { return SizeExpr; }
+ QualType getElementType() const { return ElementType; }
+ SourceLocation getAttributeLoc() const { return Loc; }
+ VectorType::VectorKind getVectorKind() const {
+ return VectorType::VectorKind(VectorTypeBits.VecKind);
+ }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == DependentVector;
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Context, getElementType(), getSizeExpr(), getVectorKind());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
+ QualType ElementType, const Expr *SizeExpr,
+ VectorType::VectorKind VecKind);
+};
+
/// ExtVectorType - Extended vector type. This type is created using
/// __attribute__((ext_vector_type(n)), where "n" is the number of elements.
/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This
@@ -3081,24 +3233,24 @@ public:
class ExtInfo {
friend class FunctionType;
- // Feel free to rearrange or add bits, but if you go over 11,
+ // Feel free to rearrange or add bits, but if you go over 12,
// you'll need to adjust both the Bits field below and
// Type::FunctionTypeBitfields.
- // | CC |noreturn|produces|nocallersavedregs|regparm|
- // |0 .. 4| 5 | 6 | 7 |8 .. 10|
+ // | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck|
+ // |0 .. 4| 5 | 6 | 7 |8 .. 10| 11 |
//
// regparm is either 0 (no regparm attribute) or the regparm value+1.
enum { CallConvMask = 0x1F };
enum { NoReturnMask = 0x20 };
enum { ProducesResultMask = 0x40 };
enum { NoCallerSavedRegsMask = 0x80 };
+ enum { NoCfCheckMask = 0x800 };
enum {
RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask |
- NoCallerSavedRegsMask),
+ NoCallerSavedRegsMask | NoCfCheckMask),
RegParmOffset = 8
}; // Assumed to be the last field
-
uint16_t Bits = CC_C;
ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {}
@@ -3107,12 +3259,13 @@ public:
// Constructor with no defaults. Use this when you know that you
// have all the elements (when reading an AST file for example).
ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc,
- bool producesResult, bool noCallerSavedRegs) {
+ bool producesResult, bool noCallerSavedRegs, bool NoCfCheck) {
assert((!hasRegParm || regParm < 7) && "Invalid regparm value");
Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) |
(producesResult ? ProducesResultMask : 0) |
(noCallerSavedRegs ? NoCallerSavedRegsMask : 0) |
- (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0);
+ (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) |
+ (NoCfCheck ? NoCfCheckMask : 0);
}
// Constructor with all defaults. Use when for example creating a
@@ -3126,10 +3279,11 @@ public:
bool getNoReturn() const { return Bits & NoReturnMask; }
bool getProducesResult() const { return Bits & ProducesResultMask; }
bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; }
+ bool getNoCfCheck() const { return Bits & NoCfCheckMask; }
bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; }
unsigned getRegParm() const {
- unsigned RegParm = Bits >> RegParmOffset;
+ unsigned RegParm = (Bits & RegParmMask) >> RegParmOffset;
if (RegParm > 0)
--RegParm;
return RegParm;
@@ -3168,6 +3322,13 @@ public:
return ExtInfo(Bits & ~NoCallerSavedRegsMask);
}
+ ExtInfo withNoCfCheck(bool noCfCheck) const {
+ if (noCfCheck)
+ return ExtInfo(Bits | NoCfCheckMask);
+ else
+ return ExtInfo(Bits & ~NoCfCheckMask);
+ }
+
ExtInfo withRegParm(unsigned RegParm) const {
assert(RegParm < 7 && "Invalid regparm value");
return ExtInfo((Bits & ~RegParmMask) |
@@ -3214,7 +3375,7 @@ public:
bool isVolatile() const { return getTypeQuals() & Qualifiers::Volatile; }
bool isRestrict() const { return getTypeQuals() & Qualifiers::Restrict; }
- /// \brief Determine the type of an expression that calls a function of
+ /// Determine the type of an expression that calls a function of
/// this type.
QualType getCallResultType(const ASTContext &Context) const {
return getReturnType().getNonLValueExprType(Context);
@@ -3367,7 +3528,7 @@ public:
/// Explicitly-specified list of exception types.
ArrayRef<QualType> Exceptions;
- /// Noexcept expression, if this is EST_ComputedNoexcept.
+ /// Noexcept expression, if this is a computed noexcept specification.
Expr *NoexceptExpr = nullptr;
/// The function whose exception specification this is, for
@@ -3409,7 +3570,7 @@ public:
private:
friend class ASTContext; // ASTContext creates these.
- /// \brief Determine whether there are any argument types that
+ /// Determine whether there are any argument types that
/// contain an unexpanded parameter pack.
static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray,
unsigned numArgs) {
@@ -3464,26 +3625,41 @@ private:
assert(hasExtParameterInfos());
// Find the end of the exception specification.
- const char *ptr = reinterpret_cast<const char *>(exception_begin());
+ const auto *ptr = reinterpret_cast<const char *>(exception_begin());
ptr += getExceptionSpecSize();
return reinterpret_cast<const ExtParameterInfo *>(ptr);
}
- size_t getExceptionSpecSize() const {
- switch (getExceptionSpecType()) {
- case EST_None: return 0;
- case EST_DynamicNone: return 0;
- case EST_MSAny: return 0;
- case EST_BasicNoexcept: return 0;
- case EST_Unparsed: return 0;
- case EST_Dynamic: return getNumExceptions() * sizeof(QualType);
- case EST_ComputedNoexcept: return sizeof(Expr*);
- case EST_Uninstantiated: return 2 * sizeof(FunctionDecl*);
- case EST_Unevaluated: return sizeof(FunctionDecl*);
+ static size_t getExceptionSpecSize(ExceptionSpecificationType EST,
+ unsigned NumExceptions) {
+ switch (EST) {
+ case EST_None:
+ case EST_DynamicNone:
+ case EST_MSAny:
+ case EST_BasicNoexcept:
+ case EST_Unparsed:
+ return 0;
+
+ case EST_Dynamic:
+ return NumExceptions * sizeof(QualType);
+
+ case EST_DependentNoexcept:
+ case EST_NoexceptFalse:
+ case EST_NoexceptTrue:
+ return sizeof(Expr *);
+
+ case EST_Uninstantiated:
+ return 2 * sizeof(FunctionDecl *);
+
+ case EST_Unevaluated:
+ return sizeof(FunctionDecl *);
}
llvm_unreachable("bad exception specification kind");
}
+ size_t getExceptionSpecSize() const {
+ return getExceptionSpecSize(getExceptionSpecType(), getNumExceptions());
+ }
public:
unsigned getNumParams() const { return NumParams; }
@@ -3507,7 +3683,7 @@ public:
EPI.RefQualifier = getRefQualifier();
if (EPI.ExceptionSpec.Type == EST_Dynamic) {
EPI.ExceptionSpec.Exceptions = exceptions();
- } else if (EPI.ExceptionSpec.Type == EST_ComputedNoexcept) {
+ } else if (isComputedNoexcept(EPI.ExceptionSpec.Type)) {
EPI.ExceptionSpec.NoexceptExpr = getNoexceptExpr();
} else if (EPI.ExceptionSpec.Type == EST_Uninstantiated) {
EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl();
@@ -3547,39 +3723,19 @@ public:
/// spec.
bool hasInstantiationDependentExceptionSpec() const;
- /// Result type of getNoexceptSpec().
- enum NoexceptResult {
- /// There is no noexcept specifier.
- NR_NoNoexcept,
-
- /// The noexcept specifier has a bad expression.
- NR_BadNoexcept,
-
- /// The noexcept specifier is dependent.
- NR_Dependent,
-
- /// The noexcept specifier evaluates to false.
- NR_Throw,
-
- /// The noexcept specifier evaluates to true.
- NR_Nothrow
- };
-
- /// Get the meaning of the noexcept spec on this function, if any.
- NoexceptResult getNoexceptSpec(const ASTContext &Ctx) const;
unsigned getNumExceptions() const { return NumExceptions; }
QualType getExceptionType(unsigned i) const {
assert(i < NumExceptions && "Invalid exception number!");
return exception_begin()[i];
}
Expr *getNoexceptExpr() const {
- if (getExceptionSpecType() != EST_ComputedNoexcept)
+ if (!isComputedNoexcept(getExceptionSpecType()))
return nullptr;
// NoexceptExpr sits where the arguments end.
return *reinterpret_cast<Expr *const *>(param_type_end());
}
- /// \brief If this function type has an exception specification which hasn't
+ /// If this function type has an exception specification which hasn't
/// been determined yet (either because it has not been evaluated or because
/// it has not been instantiated), this is the function whose exception
/// specification is represented by this type.
@@ -3590,7 +3746,7 @@ public:
return reinterpret_cast<FunctionDecl *const *>(param_type_end())[0];
}
- /// \brief If this function type has an uninstantiated exception
+ /// If this function type has an uninstantiated exception
/// specification, this is the function whose exception specification
/// should be instantiated to find the exception specification for
/// this type.
@@ -3602,14 +3758,14 @@ public:
/// Determine whether this function type has a non-throwing exception
/// specification.
- CanThrowResult canThrow(const ASTContext &Ctx) const;
+ CanThrowResult canThrow() const;
/// Determine whether this function type has a non-throwing exception
/// specification. If this depends on template arguments, returns
/// \c ResultIfDependent.
- bool isNothrow(const ASTContext &Ctx, bool ResultIfDependent = false) const {
- return ResultIfDependent ? canThrow(Ctx) != CT_Can
- : canThrow(Ctx) == CT_Cannot;
+ bool isNothrow(bool ResultIfDependent = false) const {
+ return ResultIfDependent ? canThrow() != CT_Can
+ : canThrow() == CT_Cannot;
}
bool isVariadic() const { return Variadic; }
@@ -3719,7 +3875,7 @@ public:
bool Canonical);
};
-/// \brief Represents the dependent type named by a dependently-scoped
+/// Represents the dependent type named by a dependently-scoped
/// typename using declaration, e.g.
/// using typename Base<T>::foo;
///
@@ -3790,16 +3946,16 @@ protected:
public:
Expr *getUnderlyingExpr() const { return TOExpr; }
- /// \brief Remove a single level of sugar.
+ /// Remove a single level of sugar.
QualType desugar() const;
- /// \brief Returns whether this type directly provides sugar.
+ /// Returns whether this type directly provides sugar.
bool isSugared() const;
static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
};
-/// \brief Internal representation of canonical, dependent
+/// Internal representation of canonical, dependent
/// `typeof(expr)` types.
///
/// This class is used internally by the ASTContext to manage
@@ -3839,10 +3995,10 @@ class TypeOfType : public Type {
public:
QualType getUnderlyingType() const { return TOType; }
- /// \brief Remove a single level of sugar.
+ /// Remove a single level of sugar.
QualType desugar() const { return getUnderlyingType(); }
- /// \brief Returns whether this type directly provides sugar.
+ /// Returns whether this type directly provides sugar.
bool isSugared() const { return true; }
static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
@@ -3862,16 +4018,16 @@ public:
Expr *getUnderlyingExpr() const { return E; }
QualType getUnderlyingType() const { return UnderlyingType; }
- /// \brief Remove a single level of sugar.
+ /// Remove a single level of sugar.
QualType desugar() const;
- /// \brief Returns whether this type directly provides sugar.
+ /// Returns whether this type directly provides sugar.
bool isSugared() const;
static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
};
-/// \brief Internal representation of canonical, dependent
+/// Internal representation of canonical, dependent
/// decltype(expr) types.
///
/// This class is used internally by the ASTContext to manage
@@ -3927,7 +4083,7 @@ public:
}
};
-/// \brief Internal representation of canonical, dependent
+/// Internal representation of canonical, dependent
/// __underlying_type(type) types.
///
/// This class is used internally by the ASTContext to manage
@@ -4054,6 +4210,7 @@ public:
// No operand.
attr_noreturn,
+ attr_nocf_check,
attr_cdecl,
attr_fastcall,
attr_stdcall,
@@ -4246,7 +4403,7 @@ public:
}
};
-/// \brief Represents the result of substituting a type for a template
+/// Represents the result of substituting a type for a template
/// type parameter.
///
/// Within an instantiated template, all template type parameters have
@@ -4297,7 +4454,7 @@ public:
}
};
-/// \brief Represents the result of substituting a set of types for a template
+/// Represents the result of substituting a set of types for a template
/// type parameter pack.
///
/// When a pack expansion in the source code contains multiple parameter packs
@@ -4312,14 +4469,14 @@ public:
class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- /// \brief The original type parameter.
+ /// The original type parameter.
const TemplateTypeParmType *Replaced;
- /// \brief A pointer to the set of template arguments that this
+ /// A pointer to the set of template arguments that this
/// parameter pack is instantiated with.
const TemplateArgument *Arguments;
- /// \brief The number of template arguments in \c Arguments.
+ /// The number of template arguments in \c Arguments.
unsigned NumArguments;
SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
@@ -4349,7 +4506,7 @@ public:
}
};
-/// \brief Common base class for placeholders for types that get replaced by
+/// Common base class for placeholders for types that get replaced by
/// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced
/// class template types, and (eventually) constrained type names from the C++
/// Concepts TS.
@@ -4382,7 +4539,7 @@ public:
bool isSugared() const { return !isCanonicalUnqualified(); }
QualType desugar() const { return getCanonicalTypeInternal(); }
- /// \brief Get the type deduced for this placeholder type, or null if it's
+ /// Get the type deduced for this placeholder type, or null if it's
/// either not been deduced or was deduced to a dependent type.
QualType getDeducedType() const {
return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
@@ -4397,7 +4554,7 @@ public:
}
};
-/// \brief Represents a C++11 auto or C++14 decltype(auto) type.
+/// Represents a C++11 auto or C++14 decltype(auto) type.
class AutoType : public DeducedType, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
@@ -4433,7 +4590,7 @@ public:
}
};
-/// \brief Represents a C++17 deduced template specialization type.
+/// Represents a C++17 deduced template specialization type.
class DeducedTemplateSpecializationType : public DeducedType,
public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
@@ -4470,7 +4627,7 @@ public:
}
};
-/// \brief Represents a type template specialization; the template
+/// Represents a type template specialization; the template
/// must be a class template, a type alias template, or a template
/// template parameter. A template which cannot be resolved to one of
/// these, e.g. because it is written with a dependent scope
@@ -4490,7 +4647,7 @@ public:
/// TemplateArguments, followed by a QualType representing the
/// non-canonical aliased type when the template is a type alias
/// template.
-class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateSpecializationType
+class alignas(8) TemplateSpecializationType
: public Type,
public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
@@ -4530,7 +4687,7 @@ public:
return isa<InjectedClassNameType>(getCanonicalTypeInternal());
}
- /// \brief Determine if this template specialization type is for a type alias
+ /// Determine if this template specialization type is for a type alias
/// template that has been substituted.
///
/// Nearly every template specialization type whose template is an alias
@@ -4599,7 +4756,7 @@ public:
}
};
-/// \brief Print a template argument list, including the '<' and '>'
+/// Print a template argument list, including the '<' and '>'
/// enclosing the template arguments.
void printTemplateArgumentList(raw_ostream &OS,
ArrayRef<TemplateArgument> Args,
@@ -4682,47 +4839,47 @@ public:
}
};
-/// \brief The kind of a tag type.
+/// The kind of a tag type.
enum TagTypeKind {
- /// \brief The "struct" keyword.
+ /// The "struct" keyword.
TTK_Struct,
- /// \brief The "__interface" keyword.
+ /// The "__interface" keyword.
TTK_Interface,
- /// \brief The "union" keyword.
+ /// The "union" keyword.
TTK_Union,
- /// \brief The "class" keyword.
+ /// The "class" keyword.
TTK_Class,
- /// \brief The "enum" keyword.
+ /// The "enum" keyword.
TTK_Enum
};
-/// \brief The elaboration keyword that precedes a qualified type name or
+/// The elaboration keyword that precedes a qualified type name or
/// introduces an elaborated-type-specifier.
enum ElaboratedTypeKeyword {
- /// \brief The "struct" keyword introduces the elaborated-type-specifier.
+ /// The "struct" keyword introduces the elaborated-type-specifier.
ETK_Struct,
- /// \brief The "__interface" keyword introduces the elaborated-type-specifier.
+ /// The "__interface" keyword introduces the elaborated-type-specifier.
ETK_Interface,
- /// \brief The "union" keyword introduces the elaborated-type-specifier.
+ /// The "union" keyword introduces the elaborated-type-specifier.
ETK_Union,
- /// \brief The "class" keyword introduces the elaborated-type-specifier.
+ /// The "class" keyword introduces the elaborated-type-specifier.
ETK_Class,
- /// \brief The "enum" keyword introduces the elaborated-type-specifier.
+ /// The "enum" keyword introduces the elaborated-type-specifier.
ETK_Enum,
- /// \brief The "typename" keyword precedes the qualified type name, e.g.,
+ /// The "typename" keyword precedes the qualified type name, e.g.,
/// \c typename T::type.
ETK_Typename,
- /// \brief No keyword precedes the qualified type name.
+ /// No keyword precedes the qualified type name.
ETK_None
};
@@ -4773,7 +4930,7 @@ public:
static CannotCastToThisType classof(const Type *);
};
-/// \brief Represents a type that was referred to using an elaborated type
+/// Represents a type that was referred to using an elaborated type
/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type,
/// or both.
///
@@ -4790,14 +4947,18 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
/// The type that this qualified name refers to.
QualType NamedType;
+ /// The (re)declaration of this tag type owned by this occurrence, or nullptr
+ /// if none.
+ TagDecl *OwnedTagDecl;
+
ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
- QualType NamedType, QualType CanonType)
+ QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl)
: TypeWithKeyword(Keyword, Elaborated, CanonType,
NamedType->isDependentType(),
NamedType->isInstantiationDependentType(),
NamedType->isVariablyModifiedType(),
NamedType->containsUnexpandedParameterPack()),
- NNS(NNS), NamedType(NamedType) {
+ NNS(NNS), NamedType(NamedType), OwnedTagDecl(OwnedTagDecl) {
assert(!(Keyword == ETK_None && NNS == nullptr) &&
"ElaboratedType cannot have elaborated type keyword "
"and name qualifier both null.");
@@ -4818,15 +4979,21 @@ public:
/// Returns whether this type directly provides sugar.
bool isSugared() const { return true; }
+ /// Return the (re)declaration of this type owned by this occurrence of this
+ /// type, or nullptr if none.
+ TagDecl *getOwnedTagDecl() const { return OwnedTagDecl; }
+
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getKeyword(), NNS, NamedType);
+ Profile(ID, getKeyword(), NNS, NamedType, OwnedTagDecl);
}
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, QualType NamedType) {
+ NestedNameSpecifier *NNS, QualType NamedType,
+ TagDecl *OwnedTagDecl) {
ID.AddInteger(Keyword);
ID.AddPointer(NNS);
NamedType.Profile(ID);
+ ID.AddPointer(OwnedTagDecl);
}
static bool classof(const Type *T) {
@@ -4834,7 +5001,7 @@ public:
}
};
-/// \brief Represents a qualified type name for which the type name is
+/// Represents a qualified type name for which the type name is
/// dependent.
///
/// DependentNameType represents a class of dependent types that involve a
@@ -4849,10 +5016,10 @@ public:
class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
- /// \brief The nested name specifier containing the qualifier.
+ /// The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;
- /// \brief The type that this typename specifier refers to.
+ /// The type that this typename specifier refers to.
const IdentifierInfo *Name;
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
@@ -4898,7 +5065,7 @@ public:
/// Represents a template specialization type whose template cannot be
/// resolved, e.g.
/// A<T>::template B<T>
-class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType
+class alignas(8) DependentTemplateSpecializationType
: public TypeWithKeyword,
public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
@@ -4909,7 +5076,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType
/// The identifier of the template.
const IdentifierInfo *Name;
- /// \brief The number of template arguments named in this class template
+ /// The number of template arguments named in this class template
/// specialization.
unsigned NumArgs;
@@ -4931,12 +5098,12 @@ public:
NestedNameSpecifier *getQualifier() const { return NNS; }
const IdentifierInfo *getIdentifier() const { return Name; }
- /// \brief Retrieve the template arguments.
+ /// Retrieve the template arguments.
const TemplateArgument *getArgs() const {
return getArgBuffer();
}
- /// \brief Retrieve the number of template arguments.
+ /// Retrieve the number of template arguments.
unsigned getNumArgs() const { return NumArgs; }
const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
@@ -4969,7 +5136,7 @@ public:
}
};
-/// \brief Represents a pack expansion of types.
+/// Represents a pack expansion of types.
///
/// Pack expansions are part of C++11 variadic templates. A pack
/// expansion contains a pattern, which itself contains one or more
@@ -4994,10 +5161,10 @@ public:
class PackExpansionType : public Type, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
- /// \brief The pattern of the pack expansion.
+ /// The pattern of the pack expansion.
QualType Pattern;
- /// \brief The number of expansions that this pack expansion will
+ /// The number of expansions that this pack expansion will
/// generate when substituted (+1), or indicates that
///
/// This field will only have a non-zero value when some of the parameter
@@ -5015,12 +5182,12 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
NumExpansions(NumExpansions ? *NumExpansions + 1 : 0) {}
public:
- /// \brief Retrieve the pattern of this pack expansion, which is the
+ /// Retrieve the pattern of this pack expansion, which is the
/// type that will be repeatedly instantiated when instantiating the
/// pack expansion itself.
QualType getPattern() const { return Pattern; }
- /// \brief Retrieve the number of expansions that this pack expansion will
+ /// Retrieve the number of expansions that this pack expansion will
/// generate, if known.
Optional<unsigned> getNumExpansions() const {
if (NumExpansions)
@@ -5418,8 +5585,8 @@ public:
inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const {
QualType baseType = getBaseType();
- while (const ObjCObjectType *ObjT = baseType->getAs<ObjCObjectType>()) {
- if (const ObjCInterfaceType *T = dyn_cast<ObjCInterfaceType>(ObjT))
+ while (const auto *ObjT = baseType->getAs<ObjCObjectType>()) {
+ if (const auto *T = dyn_cast<ObjCInterfaceType>(ObjT))
return T->getDecl();
baseType = ObjT->getBaseType();
@@ -5841,10 +6008,10 @@ inline Qualifiers::GC QualType::getObjCGCAttr() const {
}
inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) {
- if (const PointerType *PT = t.getAs<PointerType>()) {
- if (const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>())
+ if (const auto *PT = t.getAs<PointerType>()) {
+ if (const auto *FT = PT->getPointeeType()->getAs<FunctionType>())
return FT->getExtInfo();
- } else if (const FunctionType *FT = t.getAs<FunctionType>())
+ } else if (const auto *FT = t.getAs<FunctionType>())
return FT->getExtInfo();
return FunctionType::ExtInfo();
@@ -5889,7 +6056,7 @@ inline bool QualType::isAtLeastAsQualifiedAs(QualType other) const {
/// analysis, the expression designates the object or function
/// denoted by the reference, and the expression is an lvalue.
inline QualType QualType::getNonReferenceType() const {
- if (const ReferenceType *RefType = (*this)->getAs<ReferenceType>())
+ if (const auto *RefType = (*this)->getAs<ReferenceType>())
return RefType->getPointeeType();
else
return *this;
@@ -5964,7 +6131,7 @@ inline bool Type::isRValueReferenceType() const {
}
inline bool Type::isFunctionPointerType() const {
- if (const PointerType *T = getAs<PointerType>())
+ if (const auto *T = getAs<PointerType>())
return T->getPointeeType()->isFunctionType();
else
return false;
@@ -5975,14 +6142,14 @@ inline bool Type::isMemberPointerType() const {
}
inline bool Type::isMemberFunctionPointerType() const {
- if (const MemberPointerType* T = getAs<MemberPointerType>())
+ if (const auto *T = getAs<MemberPointerType>())
return T->isMemberFunctionPointer();
else
return false;
}
inline bool Type::isMemberDataPointerType() const {
- if (const MemberPointerType* T = getAs<MemberPointerType>())
+ if (const auto *T = getAs<MemberPointerType>())
return T->isMemberDataPointer();
else
return false;
@@ -6054,31 +6221,31 @@ inline bool Type::isAtomicType() const {
}
inline bool Type::isObjCQualifiedIdType() const {
- if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+ if (const auto *OPT = getAs<ObjCObjectPointerType>())
return OPT->isObjCQualifiedIdType();
return false;
}
inline bool Type::isObjCQualifiedClassType() const {
- if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+ if (const auto *OPT = getAs<ObjCObjectPointerType>())
return OPT->isObjCQualifiedClassType();
return false;
}
inline bool Type::isObjCIdType() const {
- if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+ if (const auto *OPT = getAs<ObjCObjectPointerType>())
return OPT->isObjCIdType();
return false;
}
inline bool Type::isObjCClassType() const {
- if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+ if (const auto *OPT = getAs<ObjCObjectPointerType>())
return OPT->isObjCClassType();
return false;
}
inline bool Type::isObjCSelType() const {
- if (const PointerType *OPT = getAs<PointerType>())
+ if (const auto *OPT = getAs<PointerType>())
return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel);
return false;
}
@@ -6141,13 +6308,13 @@ inline bool Type::isSpecificBuiltinType(unsigned K) const {
}
inline bool Type::isPlaceholderType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
+ if (const auto *BT = dyn_cast<BuiltinType>(this))
return BT->isPlaceholderType();
return false;
}
inline const BuiltinType *Type::getAsPlaceholderType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
+ if (const auto *BT = dyn_cast<BuiltinType>(this))
if (BT->isPlaceholderType())
return BT;
return nullptr;
@@ -6155,32 +6322,44 @@ inline const BuiltinType *Type::getAsPlaceholderType() const {
inline bool Type::isSpecificPlaceholderType(unsigned K) const {
assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K));
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
+ if (const auto *BT = dyn_cast<BuiltinType>(this))
return (BT->getKind() == (BuiltinType::Kind) K);
return false;
}
inline bool Type::isNonOverloadPlaceholderType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
+ if (const auto *BT = dyn_cast<BuiltinType>(this))
return BT->isNonOverloadPlaceholderType();
return false;
}
inline bool Type::isVoidType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() == BuiltinType::Void;
return false;
}
inline bool Type::isHalfType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() == BuiltinType::Half;
// FIXME: Should we allow complex __fp16? Probably not.
return false;
}
+inline bool Type::isFloat16Type() const {
+ if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
+ return BT->getKind() == BuiltinType::Float16;
+ return false;
+}
+
+inline bool Type::isFloat128Type() const {
+ if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
+ return BT->getKind() == BuiltinType::Float128;
+ return false;
+}
+
inline bool Type::isNullPtrType() const {
- if (const BuiltinType *BT = getAs<BuiltinType>())
+ if (const auto *BT = getAs<BuiltinType>())
return BT->getKind() == BuiltinType::NullPtr;
return false;
}
@@ -6189,7 +6368,7 @@ bool IsEnumDeclComplete(EnumDecl *);
bool IsEnumDeclScoped(EnumDecl *);
inline bool Type::isIntegerType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Bool &&
BT->getKind() <= BuiltinType::Int128;
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
@@ -6201,8 +6380,46 @@ inline bool Type::isIntegerType() const {
return false;
}
+inline bool Type::isFixedPointType() const {
+ if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
+ return BT->getKind() >= BuiltinType::ShortAccum &&
+ BT->getKind() <= BuiltinType::SatULongFract;
+ }
+ return false;
+}
+
+inline bool Type::isSaturatedFixedPointType() const {
+ if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
+ return BT->getKind() >= BuiltinType::SatShortAccum &&
+ BT->getKind() <= BuiltinType::SatULongFract;
+ }
+ return false;
+}
+
+inline bool Type::isUnsaturatedFixedPointType() const {
+ return isFixedPointType() && !isSaturatedFixedPointType();
+}
+
+inline bool Type::isSignedFixedPointType() const {
+ if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
+ return ((BT->getKind() >= BuiltinType::ShortAccum &&
+ BT->getKind() <= BuiltinType::LongAccum) ||
+ (BT->getKind() >= BuiltinType::ShortFract &&
+ BT->getKind() <= BuiltinType::LongFract) ||
+ (BT->getKind() >= BuiltinType::SatShortAccum &&
+ BT->getKind() <= BuiltinType::SatLongAccum) ||
+ (BT->getKind() >= BuiltinType::SatShortFract &&
+ BT->getKind() <= BuiltinType::SatLongFract));
+ }
+ return false;
+}
+
+inline bool Type::isUnsignedFixedPointType() const {
+ return isFixedPointType() && !isSignedFixedPointType();
+}
+
inline bool Type::isScalarType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() > BuiltinType::Void &&
BT->getKind() <= BuiltinType::NullPtr;
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
@@ -6217,20 +6434,20 @@ inline bool Type::isScalarType() const {
}
inline bool Type::isIntegralOrEnumerationType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Bool &&
BT->getKind() <= BuiltinType::Int128;
// Check for a complete enum type; incomplete enum types are not properly an
// enumeration type in the sense required here.
- if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
+ if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
return IsEnumDeclComplete(ET->getDecl());
return false;
}
inline bool Type::isBooleanType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() == BuiltinType::Bool;
return false;
}
@@ -6240,13 +6457,13 @@ inline bool Type::isUndeducedType() const {
return DT && !DT->isDeduced();
}
-/// \brief Determines whether this is a type for which one can define
+/// Determines whether this is a type for which one can define
/// an overloaded operator.
inline bool Type::isOverloadableType() const {
return isDependentType() || isRecordType() || isEnumeralType();
}
-/// \brief Determines whether this type can decay to a pointer type.
+/// Determines whether this type can decay to a pointer type.
inline bool Type::canDecayToPointerType() const {
return isFunctionType() || isArrayType();
}
@@ -6307,7 +6524,7 @@ template <typename T> const T *Type::getAs() const {
"ArrayType cannot be used with getAs!");
// If this is directly a T type, return it.
- if (const T *Ty = dyn_cast<T>(this))
+ if (const auto *Ty = dyn_cast<T>(this))
return Ty;
// If the canonical form of this type isn't the right kind, reject it.
@@ -6323,7 +6540,7 @@ template <typename T> const T *Type::getAsAdjusted() const {
static_assert(!TypeIsArrayType<T>::value, "ArrayType cannot be used with getAsAdjusted!");
// If this is directly a T type, return it.
- if (const T *Ty = dyn_cast<T>(this))
+ if (const auto *Ty = dyn_cast<T>(this))
return Ty;
// If the canonical form of this type isn't the right kind, reject it.
@@ -6353,7 +6570,7 @@ template <typename T> const T *Type::getAsAdjusted() const {
inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
// If this is directly an array type, return it.
- if (const ArrayType *arr = dyn_cast<ArrayType>(this))
+ if (const auto *arr = dyn_cast<ArrayType>(this))
return arr;
// If the canonical form of this type isn't the right kind, reject it.
@@ -6369,14 +6586,14 @@ template <typename T> const T *Type::castAs() const {
static_assert(!TypeIsArrayType<T>::value,
"ArrayType cannot be used with castAs!");
- if (const T *ty = dyn_cast<T>(this)) return ty;
+ if (const auto *ty = dyn_cast<T>(this)) return ty;
assert(isa<T>(CanonicalType));
return cast<T>(getUnqualifiedDesugaredType());
}
inline const ArrayType *Type::castAsArrayTypeUnsafe() const {
assert(isa<ArrayType>(CanonicalType));
- if (const ArrayType *arr = dyn_cast<ArrayType>(this)) return arr;
+ if (const auto *arr = dyn_cast<ArrayType>(this)) return arr;
return cast<ArrayType>(getUnqualifiedDesugaredType());
}
@@ -6396,6 +6613,12 @@ QualType DecayedType::getPointeeType() const {
return cast<PointerType>(Decayed)->getPointeeType();
}
+// Get the decimal string representation of a fixed point type, represented
+// as a scaled integer.
+void FixedPointValueToString(SmallVectorImpl<char> &Str,
+ const llvm::APSInt &Val,
+ unsigned Scale, unsigned Radix);
+
} // namespace clang
#endif // LLVM_CLANG_AST_TYPE_H
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index b805160a27807..25cd014efe5f4 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Defines the clang::TypeLoc interface and its subclasses.
+/// Defines the clang::TypeLoc interface and its subclasses.
//
//===----------------------------------------------------------------------===//
@@ -49,7 +49,7 @@ class UnresolvedUsingTypenameDecl;
class Class##TypeLoc;
#include "clang/AST/TypeLocNodes.def"
-/// \brief Base wrapper for a particular "section" of type source info.
+/// Base wrapper for a particular "section" of type source info.
///
/// A client should use the TypeLoc subclasses through castAs()/getAs()
/// in order to get at the actual information.
@@ -67,7 +67,7 @@ public:
TypeLoc(const Type *ty, void *opaqueData)
: Ty(ty), Data(opaqueData) {}
- /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
+ /// Convert to the specified TypeLoc type, asserting that this TypeLoc
/// is of the desired type.
///
/// \pre T::isKind(*this)
@@ -80,21 +80,21 @@ public:
return t;
}
- /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
+ /// Convert to the specified TypeLoc type, returning a null TypeLoc if
/// this TypeLoc is not of the desired type.
template<typename T>
T getAs() const {
if (!T::isKind(*this))
- return T();
+ return {};
T t;
TypeLoc& tl = t;
tl = *this;
return t;
}
- /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
- /// this TypeLock is not of the desired type. It will consider type
- /// adjustments from a type that wad written as a T to another type that is
+ /// Convert to the specified TypeLoc type, returning a null TypeLoc if
+ /// this TypeLoc is not of the desired type. It will consider type
+ /// adjustments from a type that was written as a T to another type that is
/// still canonically a T (ignores parens, attributes, elaborated types, etc).
template <typename T>
T getAsAdjusted() const;
@@ -118,14 +118,14 @@ public:
bool isNull() const { return !Ty; }
explicit operator bool() const { return Ty; }
- /// \brief Returns the size of type source info data block for the given type.
+ /// Returns the size of type source info data block for the given type.
static unsigned getFullDataSizeForType(QualType Ty);
- /// \brief Returns the alignment of type source info data block for
+ /// Returns the alignment of type source info data block for
/// the given type.
static unsigned getLocalAlignmentForType(QualType Ty);
- /// \brief Get the type for which this source info wrapper provides
+ /// Get the type for which this source info wrapper provides
/// information.
QualType getType() const {
return QualType::getFromOpaquePtr(Ty);
@@ -135,18 +135,18 @@ public:
return QualType::getFromOpaquePtr(Ty).getTypePtr();
}
- /// \brief Get the pointer where source information is stored.
+ /// Get the pointer where source information is stored.
void *getOpaqueData() const {
return Data;
}
- /// \brief Get the begin source location.
+ /// Get the begin source location.
SourceLocation getBeginLoc() const;
- /// \brief Get the end source location.
+ /// Get the end source location.
SourceLocation getEndLoc() const;
- /// \brief Get the full source range.
+ /// Get the full source range.
SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getBeginLoc(), getEndLoc());
}
@@ -154,28 +154,28 @@ public:
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
- /// \brief Get the local source range.
+ /// Get the local source range.
SourceRange getLocalSourceRange() const {
return getLocalSourceRangeImpl(*this);
}
- /// \brief Returns the size of the type source info data block.
+ /// Returns the size of the type source info data block.
unsigned getFullDataSize() const {
return getFullDataSizeForType(getType());
}
- /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
+ /// Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
TypeLoc getNextTypeLoc() const {
return getNextTypeLocImpl(*this);
}
- /// \brief Skips past any qualifiers, if this is qualified.
+ /// Skips past any qualifiers, if this is qualified.
UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
TypeLoc IgnoreParens() const;
- /// \brief Find a type with the location of an explicit type qualifier.
+ /// Find a type with the location of an explicit type qualifier.
///
/// The result, if non-null, will be one of:
/// QualifiedTypeLoc
@@ -183,7 +183,7 @@ public:
/// AttributedTypeLoc, for those type attributes that behave as qualifiers
TypeLoc findExplicitQualifierLoc() const;
- /// \brief Initializes this to state that every location in this
+ /// Initializes this to state that every location in this
/// type is the given location.
///
/// This method exists to provide a simple transition for code that
@@ -192,14 +192,14 @@ public:
initializeImpl(Context, *this, Loc);
}
- /// \brief Initializes this by copying its information from another
+ /// Initializes this by copying its information from another
/// TypeLoc of the same type.
void initializeFullCopy(TypeLoc Other) {
assert(getType() == Other.getType());
copy(Other);
}
- /// \brief Initializes this by copying its information from another
+ /// Initializes this by copying its information from another
/// TypeLoc of the same type. The given size must be the full data
/// size.
void initializeFullCopy(TypeLoc Other, unsigned Size) {
@@ -235,13 +235,13 @@ private:
static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
};
-/// \brief Return the TypeLoc for a type source info.
+/// Return the TypeLoc for a type source info.
inline TypeLoc TypeSourceInfo::getTypeLoc() const {
// TODO: is this alignment already sufficient?
return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
}
-/// \brief Wrapper of type source information for a type with
+/// Wrapper of type source information for a type with
/// no direct qualifiers.
class UnqualTypeLoc : public TypeLoc {
public:
@@ -264,7 +264,7 @@ private:
}
};
-/// \brief Wrapper of type source information for a type with
+/// Wrapper of type source information for a type with
/// non-trivial direct qualifiers.
///
/// Currently, we intentionally do not provide source location for
@@ -276,7 +276,7 @@ public:
UnqualTypeLoc getUnqualifiedLoc() const {
unsigned align =
TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
- uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data);
+ auto dataInt = reinterpret_cast<uintptr_t>(Data);
dataInt = llvm::alignTo(dataInt, align);
return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
}
@@ -295,7 +295,7 @@ public:
return getUnqualifiedLoc();
}
- /// \brief Returns the size of the type source info data block that is
+ /// Returns the size of the type source info data block that is
/// specific to this type.
unsigned getLocalDataSize() const {
// In fact, we don't currently preserve any location information
@@ -303,7 +303,7 @@ public:
return 0;
}
- /// \brief Returns the alignment of the type source info data block that is
+ /// Returns the alignment of the type source info data block that is
/// specific to this type.
unsigned getLocalDataAlignment() const {
// We don't preserve any location information.
@@ -429,7 +429,7 @@ protected:
}
void *getNonLocalData() const {
- uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data);
+ auto data = reinterpret_cast<uintptr_t>(Base::Data);
data += asDerived()->getLocalDataSize();
data = llvm::alignTo(data, getNextTypeAlign());
return reinterpret_cast<void*>(data);
@@ -503,7 +503,7 @@ struct TypeSpecLocInfo {
SourceLocation NameLoc;
};
-/// \brief A reasonable base class for TypeLocs that correspond to
+/// A reasonable base class for TypeLocs that correspond to
/// types that are written as a type-specifier.
class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
TypeSpecTypeLoc,
@@ -541,7 +541,7 @@ struct BuiltinLocInfo {
SourceRange BuiltinRange;
};
-/// \brief Wrapper for source info for builtin types.
+/// Wrapper for source info for builtin types.
class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
BuiltinTypeLoc,
BuiltinType,
@@ -661,7 +661,7 @@ public:
}
};
-/// \brief Wrapper for source info for typedefs.
+/// Wrapper for source info for typedefs.
class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TypedefTypeLoc,
TypedefType> {
@@ -671,7 +671,7 @@ public:
}
};
-/// \brief Wrapper for source info for injected class names of class
+/// Wrapper for source info for injected class names of class
/// templates.
class InjectedClassNameTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
@@ -683,7 +683,7 @@ public:
}
};
-/// \brief Wrapper for source info for unresolved typename using decls.
+/// Wrapper for source info for unresolved typename using decls.
class UnresolvedUsingTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
UnresolvedUsingTypeLoc,
@@ -694,7 +694,7 @@ public:
}
};
-/// \brief Wrapper for source info for tag types. Note that this only
+/// Wrapper for source info for tag types. Note that this only
/// records source info for the name itself; a type written 'struct foo'
/// should be represented as an ElaboratedTypeLoc. We currently
/// only do that when C++ is enabled because of the expense of
@@ -705,7 +705,7 @@ class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
public:
TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
- /// \brief True if the tag was defined in this type specifier.
+ /// True if the tag was defined in this type specifier.
bool isDefinition() const {
TagDecl *D = getDecl();
return D->isCompleteDefinition() &&
@@ -713,7 +713,7 @@ public:
}
};
-/// \brief Wrapper for source info for record types.
+/// Wrapper for source info for record types.
class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
RecordTypeLoc,
RecordType> {
@@ -721,7 +721,7 @@ public:
RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
};
-/// \brief Wrapper for source info for enum types.
+/// Wrapper for source info for enum types.
class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
EnumTypeLoc,
EnumType> {
@@ -729,7 +729,7 @@ public:
EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
};
-/// \brief Wrapper for template type parameters.
+/// Wrapper for template type parameters.
class TemplateTypeParmTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TemplateTypeParmTypeLoc,
@@ -828,14 +828,14 @@ public:
}
};
-/// \brief Wrapper for substituted template type parameters.
+/// Wrapper for substituted template type parameters.
class SubstTemplateTypeParmTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
SubstTemplateTypeParmTypeLoc,
SubstTemplateTypeParmType> {
};
- /// \brief Wrapper for substituted template type parameters.
+ /// Wrapper for substituted template type parameters.
class SubstTemplateTypeParmPackTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
SubstTemplateTypeParmPackTypeLoc,
@@ -855,7 +855,7 @@ struct AttributedLocInfo {
SourceLocation AttrLoc;
};
-/// \brief Type source information for an attributed type.
+/// Type source information for an attributed type.
class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
AttributedTypeLoc,
AttributedType,
@@ -1114,7 +1114,7 @@ struct ObjCInterfaceLocInfo {
SourceLocation NameEndLoc;
};
-/// \brief Wrapper for source info for ObjC interfaces.
+/// Wrapper for source info for ObjC interfaces.
class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
ObjCInterfaceTypeLoc,
ObjCInterfaceType,
@@ -1227,7 +1227,7 @@ public:
}
};
-/// \brief Wrapper for source info for pointers decayed from arrays and
+/// Wrapper for source info for pointers decayed from arrays and
/// functions.
class DecayedTypeLoc : public InheritingConcreteTypeLoc<
AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
@@ -1267,7 +1267,7 @@ public:
}
};
-/// \brief Wrapper for source info for pointers.
+/// Wrapper for source info for pointers.
class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
PointerType> {
public:
@@ -1280,7 +1280,7 @@ public:
}
};
-/// \brief Wrapper for source info for block pointers.
+/// Wrapper for source info for block pointers.
class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
BlockPointerType> {
public:
@@ -1297,7 +1297,7 @@ struct MemberPointerLocInfo : public PointerLikeLocInfo {
TypeSourceInfo *ClassTInfo;
};
-/// \brief Wrapper for source info for member pointers.
+/// Wrapper for source info for member pointers.
class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
MemberPointerType,
MemberPointerLocInfo> {
@@ -1392,7 +1392,7 @@ struct FunctionLocInfo {
SourceLocation LocalRangeEnd;
};
-/// \brief Wrapper for source info for functions.
+/// Wrapper for source info for functions.
class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
FunctionTypeLoc,
FunctionType,
@@ -1496,7 +1496,7 @@ public:
setExceptionSpecRange(Loc);
}
- /// \brief Returns the size of the type source info data block that is
+ /// Returns the size of the type source info data block that is
/// specific to this type.
unsigned getExtraLocalDataSize() const {
unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0;
@@ -1525,7 +1525,7 @@ struct ArrayLocInfo {
Expr *Size;
};
-/// \brief Wrapper for source info for arrays.
+/// Wrapper for source info for arrays.
class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
ArrayTypeLoc,
ArrayType,
@@ -1670,7 +1670,7 @@ public:
getLocalData()->NameLoc = Loc;
}
- /// \brief - Copy the location information from the given info.
+ /// - Copy the location information from the given info.
void copy(TemplateSpecializationTypeLoc Loc) {
unsigned size = getFullDataSize();
assert(size == Loc.getFullDataSize());
@@ -1798,6 +1798,13 @@ class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
VectorType> {
};
+// FIXME: size expression and attribute locations (or keyword if we
+// ever fully support altivec syntax).
+class DependentVectorTypeLoc
+ : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ DependentVectorTypeLoc,
+ DependentVectorType> {};
+
// FIXME: size expression and attribute locations.
class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
ExtVectorTypeLoc,
@@ -1989,7 +1996,7 @@ public:
struct ElaboratedLocInfo {
SourceLocation ElaboratedKWLoc;
- /// \brief Data associated with the nested-name-specifier location.
+ /// Data associated with the nested-name-specifier location.
void *QualifierData;
};
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 66697fa0d0faf..8638f94bda143 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -75,6 +75,7 @@ DEPENDENT_TYPE(DependentSizedArray, ArrayType)
DEPENDENT_TYPE(DependentSizedExtVector, Type)
DEPENDENT_TYPE(DependentAddressSpace, Type)
TYPE(Vector, Type)
+DEPENDENT_TYPE(DependentVector, Type)
TYPE(ExtVector, VectorType)
ABSTRACT_TYPE(Function, Type)
TYPE(FunctionProto, FunctionType)
diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h
index fa64fae8824fa..d29dd6d601247 100644
--- a/include/clang/AST/TypeOrdering.h
+++ b/include/clang/AST/TypeOrdering.h
@@ -1,4 +1,4 @@
-//===-------------- TypeOrdering.h - Total ordering for types -------------===//
+//===-------------- TypeOrdering.h - Total ordering for types ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Allows QualTypes to be sorted and hence used in maps and sets.
+/// Allows QualTypes to be sorted and hence used in maps and sets.
///
/// Defines clang::QualTypeOrdering, a total ordering on clang::QualType,
/// and hence enables QualType values to be sorted and to be used in
@@ -25,7 +25,7 @@
namespace clang {
-/// \brief Function object that provides a total ordering on QualType values.
+/// Function object that provides a total ordering on QualType values.
struct QualTypeOrdering {
bool operator()(QualType T1, QualType T2) const {
return std::less<void*>()(T1.getAsOpaquePtr(), T2.getAsOpaquePtr());
diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h
index 11e5a47f1f294..75fa0ec15ce2a 100644
--- a/include/clang/AST/TypeVisitor.h
+++ b/include/clang/AST/TypeVisitor.h
@@ -22,7 +22,7 @@ namespace clang {
return static_cast<ImplClass*>(this)-> \
Visit##CLASS(static_cast<const CLASS*>(T))
-/// \brief An operation on a type.
+/// An operation on a type.
///
/// \tparam ImplClass Class implementing the operation. Must be inherited from
/// TypeVisitor.
@@ -65,7 +65,7 @@ template<typename ImplClass, typename RetTy=void>
class TypeVisitor {
public:
- /// \brief Performs the operation associated with this visitor object.
+ /// Performs the operation associated with this visitor object.
RetTy Visit(const Type *T) {
// Top switch stmt: dispatch to VisitFooType for each FooType.
switch (T->getTypeClass()) {
@@ -83,7 +83,7 @@ public:
}
#include "clang/AST/TypeNodes.def"
- /// \brief Method called if \c ImpClass doesn't provide specific handler
+ /// Method called if \c ImpClass doesn't provide specific handler
/// for some type class.
RetTy VisitType(const Type*) { return RetTy(); }
};
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index 614ff9bf2efda..d6b01cb573347 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -57,7 +57,7 @@ public:
NamedDecl *operator->() const { return **this; }
};
-/// \brief A set of unresolved declarations.
+/// A set of unresolved declarations.
class UnresolvedSetImpl {
using DeclsTy = SmallVectorImpl<DeclAccessPair>;
@@ -140,7 +140,7 @@ private:
}
};
-/// \brief A set of unresolved declarations.
+/// A set of unresolved declarations.
template <unsigned InlineCapacity> class UnresolvedSet :
public UnresolvedSetImpl {
SmallVector<DeclAccessPair, InlineCapacity> Decls;
diff --git a/include/clang/AST/VTTBuilder.h b/include/clang/AST/VTTBuilder.h
index 178139477d001..84661c8cc7f24 100644
--- a/include/clang/AST/VTTBuilder.h
+++ b/include/clang/AST/VTTBuilder.h
@@ -68,48 +68,48 @@ struct VTTComponent {
: VTableIndex(VTableIndex), VTableBase(VTableBase) {}
};
-/// \brief Class for building VTT layout information.
+/// Class for building VTT layout information.
class VTTBuilder {
ASTContext &Ctx;
- /// \brief The most derived class for which we're building this vtable.
+ /// The most derived class for which we're building this vtable.
const CXXRecordDecl *MostDerivedClass;
using VTTVTablesVectorTy = SmallVector<VTTVTable, 64>;
- /// \brief The VTT vtables.
+ /// The VTT vtables.
VTTVTablesVectorTy VTTVTables;
using VTTComponentsVectorTy = SmallVector<VTTComponent, 64>;
- /// \brief The VTT components.
+ /// The VTT components.
VTTComponentsVectorTy VTTComponents;
- /// \brief The AST record layout of the most derived class.
+ /// The AST record layout of the most derived class.
const ASTRecordLayout &MostDerivedClassLayout;
using VisitedVirtualBasesSetTy = llvm::SmallPtrSet<const CXXRecordDecl *, 4>;
using AddressPointsMapTy = llvm::DenseMap<BaseSubobject, uint64_t>;
- /// \brief The sub-VTT indices for the bases of the most derived class.
+ /// The sub-VTT indices for the bases of the most derived class.
llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
- /// \brief The secondary virtual pointer indices of all subobjects of
+ /// The secondary virtual pointer indices of all subobjects of
/// the most derived class.
llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
- /// \brief Whether the VTT builder should generate LLVM IR for the VTT.
+ /// Whether the VTT builder should generate LLVM IR for the VTT.
bool GenerateDefinition;
- /// \brief Add a vtable pointer to the VTT currently being built.
+ /// Add a vtable pointer to the VTT currently being built.
void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
const CXXRecordDecl *VTableClass);
- /// \brief Lay out the secondary VTTs of the given base subobject.
+ /// Lay out the secondary VTTs of the given base subobject.
void LayoutSecondaryVTTs(BaseSubobject Base);
- /// \brief Lay out the secondary virtual pointers for the given base
+ /// Lay out the secondary virtual pointers for the given base
/// subobject.
///
/// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
@@ -120,17 +120,17 @@ class VTTBuilder {
const CXXRecordDecl *VTableClass,
VisitedVirtualBasesSetTy &VBases);
- /// \brief Lay out the secondary virtual pointers for the given base
+ /// Lay out the secondary virtual pointers for the given base
/// subobject.
void LayoutSecondaryVirtualPointers(BaseSubobject Base,
uint64_t VTableIndex);
- /// \brief Lay out the VTTs for the virtual base classes of the given
+ /// Lay out the VTTs for the virtual base classes of the given
/// record declaration.
void LayoutVirtualVTTs(const CXXRecordDecl *RD,
VisitedVirtualBasesSetTy &VBases);
- /// \brief Lay out the VTT for the given subobject, including any
+ /// Lay out the VTT for the given subobject, including any
/// secondary VTTs, secondary virtual pointers and virtual VTTs.
void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
@@ -138,22 +138,22 @@ public:
VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
bool GenerateDefinition);
- // \brief Returns a reference to the VTT components.
+ // Returns a reference to the VTT components.
const VTTComponentsVectorTy &getVTTComponents() const {
return VTTComponents;
}
- // \brief Returns a reference to the VTT vtables.
+ // Returns a reference to the VTT vtables.
const VTTVTablesVectorTy &getVTTVTables() const {
return VTTVTables;
}
- /// \brief Returns a reference to the sub-VTT indices.
+ /// Returns a reference to the sub-VTT indices.
const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
return SubVTTIndicies;
}
- /// \brief Returns a reference to the secondary virtual pointer indices.
+ /// Returns a reference to the secondary virtual pointer indices.
const llvm::DenseMap<BaseSubobject, uint64_t> &
getSecondaryVirtualPointerIndices() const {
return SecondaryVirtualPointerIndices;
diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h
index b0b71e473516d..643103916149b 100644
--- a/include/clang/AST/VTableBuilder.h
+++ b/include/clang/AST/VTableBuilder.h
@@ -26,7 +26,7 @@
namespace clang {
class CXXRecordDecl;
-/// \brief Represents a single component in a vtable.
+/// Represents a single component in a vtable.
class VTableComponent {
public:
enum Kind {
@@ -36,13 +36,13 @@ public:
CK_RTTI,
CK_FunctionPointer,
- /// \brief A pointer to the complete destructor.
+ /// A pointer to the complete destructor.
CK_CompleteDtorPointer,
- /// \brief A pointer to the deleting destructor.
+ /// A pointer to the deleting destructor.
CK_DeletingDtorPointer,
- /// \brief An entry that is never used.
+ /// An entry that is never used.
///
/// In some cases, a vtable function pointer will end up never being
/// called. Such vtable function pointers are represented as a
@@ -93,11 +93,7 @@ public:
reinterpret_cast<uintptr_t>(MD));
}
- static VTableComponent getFromOpaqueInteger(uint64_t I) {
- return VTableComponent(I);
- }
-
- /// \brief Get the kind of this vtable component.
+ /// Get the kind of this vtable component.
Kind getKind() const {
return (Kind)(Value & 0x7);
}
@@ -226,9 +222,6 @@ private:
return static_cast<uintptr_t>(Value & ~7ULL);
}
- explicit VTableComponent(uint64_t Value)
- : Value(Value) { }
-
/// The kind is stored in the lower 3 bits of the value. For offsets, we
/// make use of the facts that classes can't be larger than 2^55 bytes,
/// so we store the offset in the lower part of the 61 bits that remain.
@@ -255,10 +248,10 @@ private:
OwningArrayRef<VTableComponent> VTableComponents;
- /// \brief Contains thunks needed by vtables, sorted by indices.
+ /// Contains thunks needed by vtables, sorted by indices.
OwningArrayRef<VTableThunkTy> VTableThunks;
- /// \brief Address points for all vtables.
+ /// Address points for all vtables.
AddressPointsMapTy AddressPoints;
public:
@@ -324,7 +317,7 @@ public:
protected:
typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
- /// \brief Contains all thunks that a given method decl will need.
+ /// Contains all thunks that a given method decl will need.
ThunksMapTy Thunks;
/// Compute and store all vtable related information (vtable layout, vbase
@@ -355,7 +348,7 @@ public:
class ItaniumVTableContext : public VTableContextBase {
private:
- /// \brief Contains the index (relative to the vtable address point)
+ /// Contains the index (relative to the vtable address point)
/// where the function pointer for a virtual function is stored.
typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
MethodVTableIndicesTy MethodVTableIndices;
@@ -368,7 +361,7 @@ private:
typedef std::pair<const CXXRecordDecl *,
const CXXRecordDecl *> ClassPairTy;
- /// \brief vtable offsets for offsets of virtual bases of a class.
+ /// vtable offsets for offsets of virtual bases of a class.
///
/// Contains the vtable offset (relative to the address point) in chars
/// where the offsets for virtual bases of a class are stored.
@@ -393,7 +386,7 @@ public:
const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset,
bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass);
- /// \brief Locate a virtual function in the vtable.
+ /// Locate a virtual function in the vtable.
///
/// Return the index (relative to the vtable address point) where the
/// function pointer for the given virtual function is stored.
@@ -479,41 +472,42 @@ struct VirtualBaseInfo {
VPtrInfoVector VBPtrPaths;
};
+struct MethodVFTableLocation {
+ /// If nonzero, holds the vbtable index of the virtual base with the vfptr.
+ uint64_t VBTableIndex;
+
+ /// If nonnull, holds the last vbase which contains the vfptr that the
+ /// method definition is adjusted to.
+ const CXXRecordDecl *VBase;
+
+ /// This is the offset of the vfptr from the start of the last vbase, or the
+ /// complete type if there are no virtual bases.
+ CharUnits VFPtrOffset;
+
+ /// Method's index in the vftable.
+ uint64_t Index;
+
+ MethodVFTableLocation()
+ : VBTableIndex(0), VBase(nullptr), VFPtrOffset(CharUnits::Zero()),
+ Index(0) {}
+
+ MethodVFTableLocation(uint64_t VBTableIndex, const CXXRecordDecl *VBase,
+ CharUnits VFPtrOffset, uint64_t Index)
+ : VBTableIndex(VBTableIndex), VBase(VBase), VFPtrOffset(VFPtrOffset),
+ Index(Index) {}
+
+ bool operator<(const MethodVFTableLocation &other) const {
+ if (VBTableIndex != other.VBTableIndex) {
+ assert(VBase != other.VBase);
+ return VBTableIndex < other.VBTableIndex;
+ }
+ return std::tie(VFPtrOffset, Index) <
+ std::tie(other.VFPtrOffset, other.Index);
+ }
+};
+
class MicrosoftVTableContext : public VTableContextBase {
public:
- struct MethodVFTableLocation {
- /// If nonzero, holds the vbtable index of the virtual base with the vfptr.
- uint64_t VBTableIndex;
-
- /// If nonnull, holds the last vbase which contains the vfptr that the
- /// method definition is adjusted to.
- const CXXRecordDecl *VBase;
-
- /// This is the offset of the vfptr from the start of the last vbase, or the
- /// complete type if there are no virtual bases.
- CharUnits VFPtrOffset;
-
- /// Method's index in the vftable.
- uint64_t Index;
-
- MethodVFTableLocation()
- : VBTableIndex(0), VBase(nullptr), VFPtrOffset(CharUnits::Zero()),
- Index(0) {}
-
- MethodVFTableLocation(uint64_t VBTableIndex, const CXXRecordDecl *VBase,
- CharUnits VFPtrOffset, uint64_t Index)
- : VBTableIndex(VBTableIndex), VBase(VBase),
- VFPtrOffset(VFPtrOffset), Index(Index) {}
-
- bool operator<(const MethodVFTableLocation &other) const {
- if (VBTableIndex != other.VBTableIndex) {
- assert(VBase != other.VBase);
- return VBTableIndex < other.VBTableIndex;
- }
- return std::tie(VFPtrOffset, Index) <
- std::tie(other.VFPtrOffset, other.Index);
- }
- };
private:
ASTContext &Context;
@@ -522,7 +516,7 @@ private:
MethodVFTableLocationsTy;
MethodVFTableLocationsTy MethodVFTableLocations;
- typedef llvm::DenseMap<const CXXRecordDecl *, VPtrInfoVector>
+ typedef llvm::DenseMap<const CXXRecordDecl *, std::unique_ptr<VPtrInfoVector>>
VFPtrLocationsMapTy;
VFPtrLocationsMapTy VFPtrLocations;
@@ -559,7 +553,7 @@ public:
const VTableLayout &getVFTableLayout(const CXXRecordDecl *RD,
CharUnits VFPtrOffset);
- const MethodVFTableLocation &getMethodVFTableLocation(GlobalDecl GD);
+ MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD);
const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) override {
// Complete destructors don't have a slot in a vftable, so no thunks needed.
@@ -569,7 +563,7 @@ public:
return VTableContextBase::getThunkInfo(GD);
}
- /// \brief Returns the index of VBase in the vbtable of Derived.
+ /// Returns the index of VBase in the vbtable of Derived.
/// VBase must be a morally virtual base of Derived.
/// The vbtable is an array of i32 offsets. The first entry is a self entry,
/// and the rest are offsets from the vbptr to virtual bases.
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
index 389af1b6e259a..324c02db3fe06 100644
--- a/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -50,7 +50,7 @@ namespace clang {
namespace ast_matchers {
-/// \brief A class to allow finding matches over the Clang AST.
+/// A class to allow finding matches over the Clang AST.
///
/// After creation, you can add multiple matchers to the MatchFinder via
/// calls to addMatcher(...).
@@ -68,52 +68,52 @@ namespace ast_matchers {
/// Not intended to be subclassed.
class MatchFinder {
public:
- /// \brief Contains all information for a given match.
+ /// Contains all information for a given match.
///
/// Every time a match is found, the MatchFinder will invoke the registered
/// MatchCallback with a MatchResult containing information about the match.
struct MatchResult {
MatchResult(const BoundNodes &Nodes, clang::ASTContext *Context);
- /// \brief Contains the nodes bound on the current match.
+ /// Contains the nodes bound on the current match.
///
/// This allows user code to easily extract matched AST nodes.
const BoundNodes Nodes;
- /// \brief Utilities for interpreting the matched AST structures.
+ /// Utilities for interpreting the matched AST structures.
/// @{
clang::ASTContext * const Context;
clang::SourceManager * const SourceManager;
/// @}
};
- /// \brief Called when the Match registered for it was successfully found
+ /// Called when the Match registered for it was successfully found
/// in the AST.
class MatchCallback {
public:
virtual ~MatchCallback();
- /// \brief Called on every match by the \c MatchFinder.
+ /// Called on every match by the \c MatchFinder.
virtual void run(const MatchResult &Result) = 0;
- /// \brief Called at the start of each translation unit.
+ /// Called at the start of each translation unit.
///
/// Optionally override to do per translation unit tasks.
virtual void onStartOfTranslationUnit() {}
- /// \brief Called at the end of each translation unit.
+ /// Called at the end of each translation unit.
///
/// Optionally override to do per translation unit tasks.
virtual void onEndOfTranslationUnit() {}
- /// \brief An id used to group the matchers.
+ /// An id used to group the matchers.
///
/// This id is used, for example, for the profiling output.
/// It defaults to "<unknown>".
virtual StringRef getID() const;
};
- /// \brief Called when parsing is finished. Intended for testing only.
+ /// Called when parsing is finished. Intended for testing only.
class ParsingDoneTestCallback {
public:
virtual ~ParsingDoneTestCallback();
@@ -125,11 +125,11 @@ public:
Profiling(llvm::StringMap<llvm::TimeRecord> &Records)
: Records(Records) {}
- /// \brief Per bucket timing information.
+ /// Per bucket timing information.
llvm::StringMap<llvm::TimeRecord> &Records;
};
- /// \brief Enables per-check timers.
+ /// Enables per-check timers.
///
/// It prints a report after match.
llvm::Optional<Profiling> CheckProfiling;
@@ -138,7 +138,7 @@ public:
MatchFinder(MatchFinderOptions Options = MatchFinderOptions());
~MatchFinder();
- /// \brief Adds a matcher to execute when running over the AST.
+ /// Adds a matcher to execute when running over the AST.
///
/// Calls 'Action' with the BoundNodes on every match.
/// Adding more than one 'NodeMatch' allows finding different matches in a
@@ -162,7 +162,7 @@ public:
MatchCallback *Action);
/// @}
- /// \brief Adds a matcher to execute when running over the AST.
+ /// Adds a matcher to execute when running over the AST.
///
/// This is similar to \c addMatcher(), but it uses the dynamic interface. It
/// is more flexible, but the lost type information enables a caller to pass
@@ -173,10 +173,10 @@ public:
bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch,
MatchCallback *Action);
- /// \brief Creates a clang ASTConsumer that finds all matches.
+ /// Creates a clang ASTConsumer that finds all matches.
std::unique_ptr<clang::ASTConsumer> newASTConsumer();
- /// \brief Calls the registered callbacks on all matches on the given \p Node.
+ /// Calls the registered callbacks on all matches on the given \p Node.
///
/// Note that there can be multiple matches on a single node, for
/// example when using decl(forEachDescendant(stmt())).
@@ -189,17 +189,17 @@ public:
ASTContext &Context);
/// @}
- /// \brief Finds all matches in the given AST.
+ /// Finds all matches in the given AST.
void matchAST(ASTContext &Context);
- /// \brief Registers a callback to notify the end of parsing.
+ /// Registers a callback to notify the end of parsing.
///
/// The provided closure is called after parsing is done, before the AST is
/// traversed. Useful for benchmarking.
/// Each call to FindAll(...) will call the closure once.
void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone);
- /// \brief For each \c Matcher<> a \c MatchCallback that will be called
+ /// For each \c Matcher<> a \c MatchCallback that will be called
/// when it matches.
struct MatchersByType {
std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *>>
@@ -211,7 +211,7 @@ public:
NestedNameSpecifierLoc;
std::vector<std::pair<TypeLocMatcher, MatchCallback *>> TypeLoc;
std::vector<std::pair<CXXCtorInitializerMatcher, MatchCallback *>> CtorInit;
- /// \brief All the callbacks in one container to simplify iteration.
+ /// All the callbacks in one container to simplify iteration.
llvm::SmallPtrSet<MatchCallback *, 16> AllCallbacks;
};
@@ -220,11 +220,11 @@ private:
MatchFinderOptions Options;
- /// \brief Called when parsing is done.
+ /// Called when parsing is done.
ParsingDoneTestCallback *ParsingDone;
};
-/// \brief Returns the results of matching \p Matcher on \p Node.
+/// Returns the results of matching \p Matcher on \p Node.
///
/// Collects the \c BoundNodes of all callback invocations when matching
/// \p Matcher on \p Node and returns the collected results.
@@ -248,12 +248,12 @@ match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
ASTContext &Context);
/// @}
-/// \brief Returns the results of matching \p Matcher on the translation unit of
+/// Returns the results of matching \p Matcher on the translation unit of
/// \p Context and collects the \c BoundNodes of all callback invocations.
template <typename MatcherT>
SmallVector<BoundNodes, 1> match(MatcherT Matcher, ASTContext &Context);
-/// \brief Returns the first result of type \c NodeT bound to \p BoundTo.
+/// Returns the first result of type \c NodeT bound to \p BoundTo.
///
/// Returns \c NULL if there is no match, or if the matching node cannot be
/// casted to \c NodeT.
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 64e7e908d51ed..58f65a39fb48b 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -92,7 +92,7 @@
namespace clang {
namespace ast_matchers {
-/// \brief Maps string IDs to AST nodes matched by parts of a matcher.
+/// Maps string IDs to AST nodes matched by parts of a matcher.
///
/// The bound nodes are generated by calling \c bind("id") on the node matchers
/// of the nodes we want to access later.
@@ -101,7 +101,7 @@ namespace ast_matchers {
/// callbacks are executed every time a match is found.
class BoundNodes {
public:
- /// \brief Returns the AST node bound to \c ID.
+ /// Returns the AST node bound to \c ID.
///
/// Returns NULL if there was no node bound to \c ID or if there is a node but
/// it cannot be converted to the specified type.
@@ -110,12 +110,12 @@ public:
return MyBoundNodes.getNodeAs<T>(ID);
}
- /// \brief Type of mapping from binding identifiers to bound nodes. This type
+ /// Type of mapping from binding identifiers to bound nodes. This type
/// is an associative container with a key type of \c std::string and a value
/// type of \c clang::ast_type_traits::DynTypedNode
using IDToNodeMap = internal::BoundNodesMap::IDToNodeMap;
- /// \brief Retrieve mapping from binding identifiers to bound nodes.
+ /// Retrieve mapping from binding identifiers to bound nodes.
const IDToNodeMap &getMap() const {
return MyBoundNodes.getMap();
}
@@ -123,14 +123,14 @@ public:
private:
friend class internal::BoundNodesTreeBuilder;
- /// \brief Create BoundNodes from a pre-filled map of bindings.
+ /// Create BoundNodes from a pre-filled map of bindings.
BoundNodes(internal::BoundNodesMap &MyBoundNodes)
: MyBoundNodes(MyBoundNodes) {}
internal::BoundNodesMap MyBoundNodes;
};
-/// \brief If the provided matcher matches a node, binds the node to \c ID.
+/// If the provided matcher matches a node, binds the node to \c ID.
///
/// FIXME: Do we want to support this now that we have bind()?
template <typename T>
@@ -139,7 +139,7 @@ internal::Matcher<T> id(StringRef ID,
return InnerMatcher.bind(ID);
}
-/// \brief Types of matchers for the top-level classes in the AST class
+/// Types of matchers for the top-level classes in the AST class
/// hierarchy.
/// @{
using DeclarationMatcher = internal::Matcher<Decl>;
@@ -151,7 +151,7 @@ using NestedNameSpecifierLocMatcher = internal::Matcher<NestedNameSpecifierLoc>;
using CXXCtorInitializerMatcher = internal::Matcher<CXXCtorInitializer>;
/// @}
-/// \brief Matches any node.
+/// Matches any node.
///
/// Useful when another matcher requires a child matcher, but there's no
/// additional constraint. This will often be used with an explicit conversion
@@ -167,7 +167,7 @@ using CXXCtorInitializerMatcher = internal::Matcher<CXXCtorInitializer>;
/// Usable as: Any Matcher
inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
-/// \brief Matches the top declaration context.
+/// Matches the top declaration context.
///
/// Given
/// \code
@@ -181,7 +181,7 @@ inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
extern const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
translationUnitDecl;
-/// \brief Matches typedef declarations.
+/// Matches typedef declarations.
///
/// Given
/// \code
@@ -193,7 +193,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl>
typedefDecl;
-/// \brief Matches typedef name declarations.
+/// Matches typedef name declarations.
///
/// Given
/// \code
@@ -205,7 +205,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
typedefNameDecl;
-/// \brief Matches type alias declarations.
+/// Matches type alias declarations.
///
/// Given
/// \code
@@ -217,7 +217,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl>
typeAliasDecl;
-/// \brief Matches type alias template declarations.
+/// Matches type alias template declarations.
///
/// typeAliasTemplateDecl() matches
/// \code
@@ -227,7 +227,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
typeAliasTemplateDecl;
-/// \brief Matches AST nodes that were expanded within the main-file.
+/// Matches AST nodes that were expanded within the main-file.
///
/// Example matches X but not Y
/// (matcher = cxxRecordDecl(isExpansionInMainFile())
@@ -248,7 +248,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
SourceManager.getExpansionLoc(Node.getLocStart()));
}
-/// \brief Matches AST nodes that were expanded within system-header-files.
+/// Matches AST nodes that were expanded within system-header-files.
///
/// Example matches Y but not X
/// (matcher = cxxRecordDecl(isExpansionInSystemHeader())
@@ -272,7 +272,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
return SourceManager.isInSystemHeader(ExpansionLoc);
}
-/// \brief Matches AST nodes that were expanded within files whose name is
+/// Matches AST nodes that were expanded within files whose name is
/// partially matching a given regex.
///
/// Example matches Y but not X
@@ -306,7 +306,7 @@ AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
return RE.match(Filename);
}
-/// \brief Matches declarations.
+/// Matches declarations.
///
/// Examples matches \c X, \c C, and the friend declaration inside \c C;
/// \code
@@ -317,7 +317,7 @@ AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
/// \endcode
extern const internal::VariadicAllOfMatcher<Decl> decl;
-/// \brief Matches a declaration of a linkage specification.
+/// Matches a declaration of a linkage specification.
///
/// Given
/// \code
@@ -328,7 +328,7 @@ extern const internal::VariadicAllOfMatcher<Decl> decl;
extern const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
linkageSpecDecl;
-/// \brief Matches a declaration of anything that could have a name.
+/// Matches a declaration of anything that could have a name.
///
/// Example matches \c X, \c S, the anonymous union type, \c i, and \c U;
/// \code
@@ -341,7 +341,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
-/// \brief Matches a declaration of label.
+/// Matches a declaration of label.
///
/// Given
/// \code
@@ -352,7 +352,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
/// matches 'FOO:'
extern const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
-/// \brief Matches a declaration of a namespace.
+/// Matches a declaration of a namespace.
///
/// Given
/// \code
@@ -364,7 +364,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl>
namespaceDecl;
-/// \brief Matches a declaration of a namespace alias.
+/// Matches a declaration of a namespace alias.
///
/// Given
/// \code
@@ -376,7 +376,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
namespaceAliasDecl;
-/// \brief Matches class, struct, and union declarations.
+/// Matches class, struct, and union declarations.
///
/// Example matches \c X, \c Z, \c U, and \c S
/// \code
@@ -387,7 +387,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;
-/// \brief Matches C++ class declarations.
+/// Matches C++ class declarations.
///
/// Example matches \c X, \c Z
/// \code
@@ -397,7 +397,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;
extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl>
cxxRecordDecl;
-/// \brief Matches C++ class template declarations.
+/// Matches C++ class template declarations.
///
/// Example matches \c Z
/// \code
@@ -406,7 +406,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, ClassTemplateDecl>
classTemplateDecl;
-/// \brief Matches C++ class template specializations.
+/// Matches C++ class template specializations.
///
/// Given
/// \code
@@ -420,7 +420,7 @@ extern const internal::VariadicDynCastAllOfMatcher<
Decl, ClassTemplateSpecializationDecl>
classTemplateSpecializationDecl;
-/// \brief Matches declarator declarations (field, variable, function
+/// Matches declarator declarations (field, variable, function
/// and non-type template parameter declarations).
///
/// Given
@@ -432,7 +432,7 @@ extern const internal::VariadicDynCastAllOfMatcher<
extern const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
declaratorDecl;
-/// \brief Matches parameter variable declarations.
+/// Matches parameter variable declarations.
///
/// Given
/// \code
@@ -443,7 +443,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl>
parmVarDecl;
-/// \brief Matches C++ access specifier declarations.
+/// Matches C++ access specifier declarations.
///
/// Given
/// \code
@@ -457,7 +457,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl>
accessSpecDecl;
-/// \brief Matches constructor initializers.
+/// Matches constructor initializers.
///
/// Examples matches \c i(42).
/// \code
@@ -469,7 +469,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl>
extern const internal::VariadicAllOfMatcher<CXXCtorInitializer>
cxxCtorInitializer;
-/// \brief Matches template arguments.
+/// Matches template arguments.
///
/// Given
/// \code
@@ -480,7 +480,7 @@ extern const internal::VariadicAllOfMatcher<CXXCtorInitializer>
/// matches 'int' in C<int>.
extern const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
-/// \brief Matches template name.
+/// Matches template name.
///
/// Given
/// \code
@@ -491,7 +491,7 @@ extern const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
/// matches 'X' in X<int>.
extern const internal::VariadicAllOfMatcher<TemplateName> templateName;
-/// \brief Matches non-type template parameter declarations.
+/// Matches non-type template parameter declarations.
///
/// Given
/// \code
@@ -503,7 +503,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl,
NonTypeTemplateParmDecl>
nonTypeTemplateParmDecl;
-/// \brief Matches template type parameter declarations.
+/// Matches template type parameter declarations.
///
/// Given
/// \code
@@ -514,7 +514,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl,
extern const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl>
templateTypeParmDecl;
-/// \brief Matches public C++ declarations.
+/// Matches public C++ declarations.
///
/// Given
/// \code
@@ -530,7 +530,7 @@ AST_MATCHER(Decl, isPublic) {
return Node.getAccess() == AS_public;
}
-/// \brief Matches protected C++ declarations.
+/// Matches protected C++ declarations.
///
/// Given
/// \code
@@ -546,7 +546,7 @@ AST_MATCHER(Decl, isProtected) {
return Node.getAccess() == AS_protected;
}
-/// \brief Matches private C++ declarations.
+/// Matches private C++ declarations.
///
/// Given
/// \code
@@ -562,7 +562,7 @@ AST_MATCHER(Decl, isPrivate) {
return Node.getAccess() == AS_private;
}
-/// \brief Matches non-static data members that are bit-fields.
+/// Matches non-static data members that are bit-fields.
///
/// Given
/// \code
@@ -577,7 +577,7 @@ AST_MATCHER(FieldDecl, isBitField) {
return Node.isBitField();
}
-/// \brief Matches non-static data members that are bit-fields of the specified
+/// Matches non-static data members that are bit-fields of the specified
/// bit width.
///
/// Given
@@ -595,7 +595,7 @@ AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) {
Node.getBitWidthValue(Finder->getASTContext()) == Width;
}
-/// \brief Matches non-static data members that have an in-class initializer.
+/// Matches non-static data members that have an in-class initializer.
///
/// Given
/// \code
@@ -616,7 +616,13 @@ AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher<Expr>,
InnerMatcher.matches(*Initializer, Finder, Builder));
}
-/// \brief Matches the specialized template of a specialization declaration.
+/// Determines whether the function is "main", which is the entry point
+/// into an executable program.
+AST_MATCHER(FunctionDecl, isMain) {
+ return Node.isMain();
+}
+
+/// Matches the specialized template of a specialization declaration.
///
/// Given
/// \code
@@ -633,13 +639,13 @@ AST_MATCHER_P(ClassTemplateSpecializationDecl, hasSpecializedTemplate,
InnerMatcher.matches(*Decl, Finder, Builder));
}
-/// \brief Matches a declaration that has been implicitly added
+/// Matches a declaration that has been implicitly added
/// by the compiler (eg. implicit default/copy constructors).
AST_MATCHER(Decl, isImplicit) {
return Node.isImplicit();
}
-/// \brief Matches classTemplateSpecializations, templateSpecializationType and
+/// Matches classTemplateSpecializations, templateSpecializationType and
/// functionDecl that have at least one TemplateArgument matching the given
/// InnerMatcher.
///
@@ -672,7 +678,7 @@ AST_POLYMORPHIC_MATCHER_P(
Builder);
}
-/// \brief Matches expressions that match InnerMatcher after any implicit AST
+/// Matches expressions that match InnerMatcher after any implicit AST
/// nodes are stripped off.
///
/// Parentheses and explicit casts are not discarded.
@@ -693,12 +699,12 @@ AST_POLYMORPHIC_MATCHER_P(
/// varDecl(hasInitializer(cxxConstructExpr()))
/// \endcode
/// only match the declarations for b and c.
-AST_MATCHER_P(Expr, ignoringImplicit, ast_matchers::internal::Matcher<Expr>,
+AST_MATCHER_P(Expr, ignoringImplicit, internal::Matcher<Expr>,
InnerMatcher) {
return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder);
}
-/// \brief Matches expressions that match InnerMatcher after any implicit casts
+/// Matches expressions that match InnerMatcher after any implicit casts
/// are stripped off.
///
/// Parentheses and explicit casts are not discarded.
@@ -728,7 +734,7 @@ AST_MATCHER_P(Expr, ignoringImpCasts,
return InnerMatcher.matches(*Node.IgnoreImpCasts(), Finder, Builder);
}
-/// \brief Matches expressions that match InnerMatcher after parentheses and
+/// Matches expressions that match InnerMatcher after parentheses and
/// casts are stripped off.
///
/// Implicit and non-C Style casts are also discarded.
@@ -749,7 +755,7 @@ AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher<Expr>, InnerMatcher) {
return InnerMatcher.matches(*Node.IgnoreParenCasts(), Finder, Builder);
}
-/// \brief Matches expressions that match InnerMatcher after implicit casts and
+/// Matches expressions that match InnerMatcher after implicit casts and
/// parentheses are stripped off.
///
/// Explicit casts are not discarded.
@@ -775,7 +781,7 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts,
return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder);
}
-/// \brief Matches types that match InnerMatcher after any parens are stripped.
+/// Matches types that match InnerMatcher after any parens are stripped.
///
/// Given
/// \code
@@ -791,7 +797,7 @@ AST_MATCHER_P(QualType, ignoringParens,
return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
}
-/// \brief Matches classTemplateSpecializations, templateSpecializationType and
+/// Matches classTemplateSpecializations, templateSpecializationType and
/// functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
///
/// Given
@@ -800,7 +806,7 @@ AST_MATCHER_P(QualType, ignoringParens,
/// A<bool, int> b;
/// A<int, bool> c;
///
-/// template<typename T> f() {};
+/// template<typename T> void f() {}
/// void func() { f<int>(); };
/// \endcode
/// classTemplateSpecializationDecl(hasTemplateArgument(
@@ -822,7 +828,7 @@ AST_POLYMORPHIC_MATCHER_P2(
return InnerMatcher.matches(List[N], Finder, Builder);
}
-/// \brief Matches if the number of template arguments equals \p N.
+/// Matches if the number of template arguments equals \p N.
///
/// Given
/// \code
@@ -839,7 +845,7 @@ AST_POLYMORPHIC_MATCHER_P(
return internal::getTemplateSpecializationArgs(Node).size() == N;
}
-/// \brief Matches a TemplateArgument that refers to a certain type.
+/// Matches a TemplateArgument that refers to a certain type.
///
/// Given
/// \code
@@ -857,7 +863,7 @@ AST_MATCHER_P(TemplateArgument, refersToType,
return InnerMatcher.matches(Node.getAsType(), Finder, Builder);
}
-/// \brief Matches a TemplateArgument that refers to a certain template.
+/// Matches a TemplateArgument that refers to a certain template.
///
/// Given
/// \code
@@ -875,17 +881,17 @@ AST_MATCHER_P(TemplateArgument, refersToTemplate,
return InnerMatcher.matches(Node.getAsTemplate(), Finder, Builder);
}
-/// \brief Matches a canonical TemplateArgument that refers to a certain
+/// Matches a canonical TemplateArgument that refers to a certain
/// declaration.
///
/// Given
/// \code
-/// template<typename T> struct A {};
-/// struct B { B* next; };
+/// struct B { int next; };
+/// template<int(B::*next_ptr)> struct A {};
/// A<&B::next> a;
/// \endcode
/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
-/// refersToDeclaration(fieldDecl(hasName("next"))))
+/// refersToDeclaration(fieldDecl(hasName("next")))))
/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
/// \c B::next
AST_MATCHER_P(TemplateArgument, refersToDeclaration,
@@ -895,12 +901,12 @@ AST_MATCHER_P(TemplateArgument, refersToDeclaration,
return false;
}
-/// \brief Matches a sugar TemplateArgument that refers to a certain expression.
+/// Matches a sugar TemplateArgument that refers to a certain expression.
///
/// Given
/// \code
-/// template<typename T> struct A {};
-/// struct B { B* next; };
+/// struct B { int next; };
+/// template<int(B::*next_ptr)> struct A {};
/// A<&B::next> a;
/// \endcode
/// templateSpecializationType(hasAnyTemplateArgument(
@@ -913,11 +919,11 @@ AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher<Expr>, InnerMatcher) {
return false;
}
-/// \brief Matches a TemplateArgument that is an integral value.
+/// Matches a TemplateArgument that is an integral value.
///
/// Given
/// \code
-/// template<int T> struct A {};
+/// template<int T> struct C {};
/// C<42> c;
/// \endcode
/// classTemplateSpecializationDecl(
@@ -928,11 +934,11 @@ AST_MATCHER(TemplateArgument, isIntegral) {
return Node.getKind() == TemplateArgument::Integral;
}
-/// \brief Matches a TemplateArgument that referes to an integral type.
+/// Matches a TemplateArgument that referes to an integral type.
///
/// Given
/// \code
-/// template<int T> struct A {};
+/// template<int T> struct C {};
/// C<42> c;
/// \endcode
/// classTemplateSpecializationDecl(
@@ -945,7 +951,7 @@ AST_MATCHER_P(TemplateArgument, refersToIntegralType,
return InnerMatcher.matches(Node.getIntegralType(), Finder, Builder);
}
-/// \brief Matches a TemplateArgument of integral type with a given value.
+/// Matches a TemplateArgument of integral type with a given value.
///
/// Note that 'Value' is a string as the template argument's value is
/// an arbitrary precision integer. 'Value' must be euqal to the canonical
@@ -953,7 +959,7 @@ AST_MATCHER_P(TemplateArgument, refersToIntegralType,
///
/// Given
/// \code
-/// template<int T> struct A {};
+/// template<int T> struct C {};
/// C<42> c;
/// \endcode
/// classTemplateSpecializationDecl(
@@ -966,7 +972,20 @@ AST_MATCHER_P(TemplateArgument, equalsIntegralValue,
return Node.getAsIntegral().toString(10) == Value;
}
-/// \brief Matches any value declaration.
+/// Matches an Objective-C autorelease pool statement.
+///
+/// Given
+/// \code
+/// @autoreleasepool {
+/// int x = 0;
+/// }
+/// \endcode
+/// autoreleasePoolStmt(stmt()) matches the declaration of "x"
+/// inside the autorelease pool.
+extern const internal::VariadicDynCastAllOfMatcher<Stmt,
+ ObjCAutoreleasePoolStmt> autoreleasePoolStmt;
+
+/// Matches any value declaration.
///
/// Example matches A, B, C and F
/// \code
@@ -975,7 +994,7 @@ AST_MATCHER_P(TemplateArgument, equalsIntegralValue,
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
-/// \brief Matches C++ constructor declarations.
+/// Matches C++ constructor declarations.
///
/// Example matches Foo::Foo() and Foo::Foo(int)
/// \code
@@ -989,7 +1008,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl>
cxxConstructorDecl;
-/// \brief Matches explicit C++ destructor declarations.
+/// Matches explicit C++ destructor declarations.
///
/// Example matches Foo::~Foo()
/// \code
@@ -1001,7 +1020,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
cxxDestructorDecl;
-/// \brief Matches enum declarations.
+/// Matches enum declarations.
///
/// Example matches X
/// \code
@@ -1011,7 +1030,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
-/// \brief Matches enum constants.
+/// Matches enum constants.
///
/// Example matches A, B, C
/// \code
@@ -1022,7 +1041,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
enumConstantDecl;
-/// \brief Matches method declarations.
+/// Matches method declarations.
///
/// Example matches y
/// \code
@@ -1031,7 +1050,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl>
cxxMethodDecl;
-/// \brief Matches conversion operator declarations.
+/// Matches conversion operator declarations.
///
/// Example matches the operator.
/// \code
@@ -1040,7 +1059,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
cxxConversionDecl;
-/// \brief Matches variable declarations.
+/// Matches variable declarations.
///
/// Note: this does not match declarations of member variables, which are
/// "field" declarations in Clang parlance.
@@ -1051,7 +1070,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
-/// \brief Matches field declarations.
+/// Matches field declarations.
///
/// Given
/// \code
@@ -1061,7 +1080,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
/// matches 'm'.
extern const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
-/// \brief Matches function declarations.
+/// Matches function declarations.
///
/// Example matches f
/// \code
@@ -1070,7 +1089,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl>
functionDecl;
-/// \brief Matches C++ function template declarations.
+/// Matches C++ function template declarations.
///
/// Example matches f
/// \code
@@ -1079,7 +1098,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl>
functionTemplateDecl;
-/// \brief Matches friend declarations.
+/// Matches friend declarations.
///
/// Given
/// \code
@@ -1089,7 +1108,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl>
/// matches 'friend void foo()'.
extern const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
-/// \brief Matches statements.
+/// Matches statements.
///
/// Given
/// \code
@@ -1099,7 +1118,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
/// matches both the compound statement '{ ++a; }' and '++a'.
extern const internal::VariadicAllOfMatcher<Stmt> stmt;
-/// \brief Matches declaration statements.
+/// Matches declaration statements.
///
/// Given
/// \code
@@ -1109,7 +1128,7 @@ extern const internal::VariadicAllOfMatcher<Stmt> stmt;
/// matches 'int a'.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
-/// \brief Matches member expressions.
+/// Matches member expressions.
///
/// Given
/// \code
@@ -1122,7 +1141,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
/// matches this->x, x, y.x, a, this->b
extern const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
-/// \brief Matches call expressions.
+/// Matches call expressions.
///
/// Example matches x.y() and y()
/// \code
@@ -1132,7 +1151,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
-/// \brief Matches lambda expressions.
+/// Matches lambda expressions.
///
/// Example matches [&](){return 5;}
/// \code
@@ -1140,7 +1159,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
-/// \brief Matches member call expressions.
+/// Matches member call expressions.
///
/// Example matches x.y()
/// \code
@@ -1150,7 +1169,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
cxxMemberCallExpr;
-/// \brief Matches ObjectiveC Message invocation expressions.
+/// Matches ObjectiveC Message invocation expressions.
///
/// The innermost message send invokes the "alloc" class method on the
/// NSString class, while the outermost message send invokes the
@@ -1162,7 +1181,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
objcMessageExpr;
-/// \brief Matches Objective-C interface declarations.
+/// Matches Objective-C interface declarations.
///
/// Example matches Foo
/// \code
@@ -1172,7 +1191,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl>
objcInterfaceDecl;
-/// \brief Matches Objective-C implementation declarations.
+/// Matches Objective-C implementation declarations.
///
/// Example matches Foo
/// \code
@@ -1182,7 +1201,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>
objcImplementationDecl;
-/// \brief Matches Objective-C protocol declarations.
+/// Matches Objective-C protocol declarations.
///
/// Example matches FooDelegate
/// \code
@@ -1192,7 +1211,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>
objcProtocolDecl;
-/// \brief Matches Objective-C category declarations.
+/// Matches Objective-C category declarations.
///
/// Example matches Foo (Additions)
/// \code
@@ -1202,7 +1221,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>
objcCategoryDecl;
-/// \brief Matches Objective-C category definitions.
+/// Matches Objective-C category definitions.
///
/// Example matches Foo (Additions)
/// \code
@@ -1212,7 +1231,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>
objcCategoryImplDecl;
-/// \brief Matches Objective-C method declarations.
+/// Matches Objective-C method declarations.
///
/// Example matches both declaration and definition of -[Foo method]
/// \code
@@ -1227,7 +1246,20 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
objcMethodDecl;
-/// \brief Matches Objective-C instance variable declarations.
+/// Matches block declarations.
+///
+/// Example matches the declaration of the nameless block printing an input
+/// integer.
+///
+/// \code
+/// myFunc(^(int p) {
+/// printf("%d", p);
+/// })
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Decl, BlockDecl>
+ blockDecl;
+
+/// Matches Objective-C instance variable declarations.
///
/// Example matches _enabled
/// \code
@@ -1239,7 +1271,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl>
objcIvarDecl;
-/// \brief Matches Objective-C property declarations.
+/// Matches Objective-C property declarations.
///
/// Example matches enabled
/// \code
@@ -1250,7 +1282,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
objcPropertyDecl;
-/// \brief Matches Objective-C \@throw statements.
+/// Matches Objective-C \@throw statements.
///
/// Example matches \@throw
/// \code
@@ -1259,7 +1291,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>
objcThrowStmt;
-/// \brief Matches Objective-C @try statements.
+/// Matches Objective-C @try statements.
///
/// Example matches @try
/// \code
@@ -1269,7 +1301,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt>
objcTryStmt;
-/// \brief Matches Objective-C @catch statements.
+/// Matches Objective-C @catch statements.
///
/// Example matches @catch
/// \code
@@ -1279,7 +1311,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>
objcCatchStmt;
-/// \brief Matches Objective-C @finally statements.
+/// Matches Objective-C @finally statements.
///
/// Example matches @finally
/// \code
@@ -1289,7 +1321,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>
objcFinallyStmt;
-/// \brief Matches expressions that introduce cleanups to be run at the end
+/// Matches expressions that introduce cleanups to be run at the end
/// of the sub-expression's evaluation.
///
/// Example matches std::string()
@@ -1299,7 +1331,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
exprWithCleanups;
-/// \brief Matches init list expressions.
+/// Matches init list expressions.
///
/// Given
/// \code
@@ -1312,7 +1344,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr>
initListExpr;
-/// \brief Matches the syntactic form of init list expressions
+/// Matches the syntactic form of init list expressions
/// (if expression have it).
AST_MATCHER_P(InitListExpr, hasSyntacticForm,
internal::Matcher<Expr>, InnerMatcher) {
@@ -1321,7 +1353,7 @@ AST_MATCHER_P(InitListExpr, hasSyntacticForm,
InnerMatcher.matches(*SyntForm, Finder, Builder));
}
-/// \brief Matches C++ initializer list expressions.
+/// Matches C++ initializer list expressions.
///
/// Given
/// \code
@@ -1336,7 +1368,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt,
CXXStdInitializerListExpr>
cxxStdInitializerListExpr;
-/// \brief Matches implicit initializers of init list expressions.
+/// Matches implicit initializers of init list expressions.
///
/// Given
/// \code
@@ -1347,7 +1379,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt,
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
implicitValueInitExpr;
-/// \brief Matches paren list expressions.
+/// Matches paren list expressions.
/// ParenListExprs don't have a predefined type and are used for late parsing.
/// In the final AST, they can be met in template declarations.
///
@@ -1365,7 +1397,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr>
parenListExpr;
-/// \brief Matches substitutions of non-type template parameters.
+/// Matches substitutions of non-type template parameters.
///
/// Given
/// \code
@@ -1379,7 +1411,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt,
SubstNonTypeTemplateParmExpr>
substNonTypeTemplateParmExpr;
-/// \brief Matches using declarations.
+/// Matches using declarations.
///
/// Given
/// \code
@@ -1390,7 +1422,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt,
/// matches \code using X::x \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
-/// \brief Matches using namespace declarations.
+/// Matches using namespace declarations.
///
/// Given
/// \code
@@ -1402,7 +1434,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
usingDirectiveDecl;
-/// \brief Matches reference to a name that can be looked up during parsing
+/// Matches reference to a name that can be looked up during parsing
/// but could not be resolved to a specific declaration.
///
/// Given
@@ -1419,7 +1451,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>
unresolvedLookupExpr;
-/// \brief Matches unresolved using value declarations.
+/// Matches unresolved using value declarations.
///
/// Given
/// \code
@@ -1434,7 +1466,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl,
UnresolvedUsingValueDecl>
unresolvedUsingValueDecl;
-/// \brief Matches unresolved using value declarations that involve the
+/// Matches unresolved using value declarations that involve the
/// typename.
///
/// Given
@@ -1453,7 +1485,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl,
UnresolvedUsingTypenameDecl>
unresolvedUsingTypenameDecl;
-/// \brief Matches parentheses used in expressions.
+/// Matches parentheses used in expressions.
///
/// Example matches (foo() + 1)
/// \code
@@ -1462,7 +1494,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl,
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
-/// \brief Matches constructor call expressions (including implicit ones).
+/// Matches constructor call expressions (including implicit ones).
///
/// Example matches string(ptr, n) and ptr within arguments of f
/// (matcher = cxxConstructExpr())
@@ -1475,7 +1507,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
cxxConstructExpr;
-/// \brief Matches unresolved constructor call expressions.
+/// Matches unresolved constructor call expressions.
///
/// Example matches T(t) in return statement of f
/// (matcher = cxxUnresolvedConstructExpr())
@@ -1487,7 +1519,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt,
CXXUnresolvedConstructExpr>
cxxUnresolvedConstructExpr;
-/// \brief Matches implicit and explicit this expressions.
+/// Matches implicit and explicit this expressions.
///
/// Example matches the implicit this expression in "return i".
/// (matcher = cxxThisExpr())
@@ -1500,7 +1532,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt,
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr>
cxxThisExpr;
-/// \brief Matches nodes where temporaries are created.
+/// Matches nodes where temporaries are created.
///
/// Example matches FunctionTakesString(GetStringByValue())
/// (matcher = cxxBindTemporaryExpr())
@@ -1511,7 +1543,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr>
cxxBindTemporaryExpr;
-/// \brief Matches nodes where temporaries are materialized.
+/// Matches nodes where temporaries are materialized.
///
/// Example: Given
/// \code
@@ -1523,17 +1555,17 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr>
/// \code
/// T u(f());
/// g(f());
+/// f().func();
/// \endcode
/// but does not match
/// \code
/// f();
-/// f().func();
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
MaterializeTemporaryExpr>
materializeTemporaryExpr;
-/// \brief Matches new expressions.
+/// Matches new expressions.
///
/// Given
/// \code
@@ -1543,7 +1575,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt,
/// matches 'new X'.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
-/// \brief Matches delete expressions.
+/// Matches delete expressions.
///
/// Given
/// \code
@@ -1554,7 +1586,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr>
cxxDeleteExpr;
-/// \brief Matches array subscript expressions.
+/// Matches array subscript expressions.
///
/// Given
/// \code
@@ -1565,7 +1597,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>
arraySubscriptExpr;
-/// \brief Matches the value of a default argument at the call site.
+/// Matches the value of a default argument at the call site.
///
/// Example matches the CXXDefaultArgExpr placeholder inserted for the
/// default value of the second parameter in the call expression f(42)
@@ -1577,7 +1609,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
cxxDefaultArgExpr;
-/// \brief Matches overloaded operator calls.
+/// Matches overloaded operator calls.
///
/// Note that if an operator isn't overloaded, it won't match. Instead, use
/// binaryOperator matcher.
@@ -1594,7 +1626,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
cxxOperatorCallExpr;
-/// \brief Matches expressions.
+/// Matches expressions.
///
/// Example matches x()
/// \code
@@ -1602,7 +1634,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
-/// \brief Matches expressions that refer to declarations.
+/// Matches expressions that refer to declarations.
///
/// Example matches x in if (x)
/// \code
@@ -1612,7 +1644,22 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr>
declRefExpr;
-/// \brief Matches if statements.
+/// Matches a reference to an ObjCIvar.
+///
+/// Example: matches "a" in "init" method:
+/// \code
+/// @implementation A {
+/// NSString *a;
+/// }
+/// - (void) init {
+/// a = @"hello";
+/// }
+//}
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr>
+ objcIvarRefExpr;
+
+/// Matches if statements.
///
/// Example matches 'if (x) {}'
/// \code
@@ -1620,7 +1667,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr>
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
-/// \brief Matches for statements.
+/// Matches for statements.
///
/// Example matches 'for (;;) {}'
/// \code
@@ -1629,7 +1676,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
-/// \brief Matches the increment statement of a for loop.
+/// Matches the increment statement of a for loop.
///
/// Example:
/// forStmt(hasIncrement(unaryOperator(hasOperatorName("++"))))
@@ -1644,7 +1691,7 @@ AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>,
InnerMatcher.matches(*Increment, Finder, Builder));
}
-/// \brief Matches the initialization statement of a for loop.
+/// Matches the initialization statement of a for loop.
///
/// Example:
/// forStmt(hasLoopInit(declStmt()))
@@ -1658,7 +1705,7 @@ AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>,
return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
}
-/// \brief Matches range-based for statements.
+/// Matches range-based for statements.
///
/// cxxForRangeStmt() matches 'for (auto a : i)'
/// \code
@@ -1668,7 +1715,7 @@ AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>,
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>
cxxForRangeStmt;
-/// \brief Matches the initialization statement of a for loop.
+/// Matches the initialization statement of a for loop.
///
/// Example:
/// forStmt(hasLoopVariable(anything()))
@@ -1682,7 +1729,7 @@ AST_MATCHER_P(CXXForRangeStmt, hasLoopVariable, internal::Matcher<VarDecl>,
return (Var != nullptr && InnerMatcher.matches(*Var, Finder, Builder));
}
-/// \brief Matches the range initialization statement of a for loop.
+/// Matches the range initialization statement of a for loop.
///
/// Example:
/// forStmt(hasRangeInit(anything()))
@@ -1696,7 +1743,7 @@ AST_MATCHER_P(CXXForRangeStmt, hasRangeInit, internal::Matcher<Expr>,
return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
}
-/// \brief Matches while statements.
+/// Matches while statements.
///
/// Given
/// \code
@@ -1706,7 +1753,7 @@ AST_MATCHER_P(CXXForRangeStmt, hasRangeInit, internal::Matcher<Expr>,
/// matches 'while (true) {}'.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
-/// \brief Matches do statements.
+/// Matches do statements.
///
/// Given
/// \code
@@ -1716,7 +1763,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
/// matches 'do {} while(true)'
extern const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
-/// \brief Matches break statements.
+/// Matches break statements.
///
/// Given
/// \code
@@ -1726,7 +1773,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
/// matches 'break'
extern const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
-/// \brief Matches continue statements.
+/// Matches continue statements.
///
/// Given
/// \code
@@ -1737,7 +1784,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt>
continueStmt;
-/// \brief Matches return statements.
+/// Matches return statements.
///
/// Given
/// \code
@@ -1747,7 +1794,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt>
/// matches 'return 1'
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
-/// \brief Matches goto statements.
+/// Matches goto statements.
///
/// Given
/// \code
@@ -1758,7 +1805,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
/// matches 'goto FOO'
extern const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
-/// \brief Matches label statements.
+/// Matches label statements.
///
/// Given
/// \code
@@ -1769,7 +1816,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
/// matches 'FOO:'
extern const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
-/// \brief Matches address of label statements (GNU extension).
+/// Matches address of label statements (GNU extension).
///
/// Given
/// \code
@@ -1782,7 +1829,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr>
addrLabelExpr;
-/// \brief Matches switch statements.
+/// Matches switch statements.
///
/// Given
/// \code
@@ -1792,47 +1839,47 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr>
/// matches 'switch(a)'.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
-/// \brief Matches case and default statements inside switch statements.
+/// Matches case and default statements inside switch statements.
///
/// Given
/// \code
/// switch(a) { case 42: break; default: break; }
/// \endcode
/// switchCase()
-/// matches 'case 42: break;' and 'default: break;'.
+/// matches 'case 42:' and 'default:'.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
-/// \brief Matches case statements inside switch statements.
+/// Matches case statements inside switch statements.
///
/// Given
/// \code
/// switch(a) { case 42: break; default: break; }
/// \endcode
/// caseStmt()
-/// matches 'case 42: break;'.
+/// matches 'case 42:'.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
-/// \brief Matches default statements inside switch statements.
+/// Matches default statements inside switch statements.
///
/// Given
/// \code
/// switch(a) { case 42: break; default: break; }
/// \endcode
/// defaultStmt()
-/// matches 'default: break;'.
+/// matches 'default:'.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt>
defaultStmt;
-/// \brief Matches compound statements.
+/// Matches compound statements.
///
-/// Example matches '{}' and '{{}}'in 'for (;;) {{}}'
+/// Example matches '{}' and '{{}}' in 'for (;;) {{}}'
/// \code
/// for (;;) {{}}
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt>
compoundStmt;
-/// \brief Matches catch statements.
+/// Matches catch statements.
///
/// \code
/// try {} catch(int i) {}
@@ -1842,7 +1889,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt>
cxxCatchStmt;
-/// \brief Matches try statements.
+/// Matches try statements.
///
/// \code
/// try {} catch(int i) {}
@@ -1851,7 +1898,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt>
/// matches 'try {}'
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
-/// \brief Matches throw expressions.
+/// Matches throw expressions.
///
/// \code
/// try { throw 5; } catch(int i) {}
@@ -1861,7 +1908,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr>
cxxThrowExpr;
-/// \brief Matches null statements.
+/// Matches null statements.
///
/// \code
/// foo();;
@@ -1870,7 +1917,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr>
/// matches the second ';'
extern const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
-/// \brief Matches asm statements.
+/// Matches asm statements.
///
/// \code
/// int i = 100;
@@ -1880,7 +1927,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
/// matches '__asm("mov al, 2")'
extern const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
-/// \brief Matches bool literals.
+/// Matches bool literals.
///
/// Example matches true
/// \code
@@ -1889,7 +1936,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>
cxxBoolLiteral;
-/// \brief Matches string literals (also matches wide string literals).
+/// Matches string literals (also matches wide string literals).
///
/// Example matches "abcd", L"abcd"
/// \code
@@ -1899,7 +1946,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral>
stringLiteral;
-/// \brief Matches character literals (also matches wchar_t).
+/// Matches character literals (also matches wchar_t).
///
/// Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral),
/// though.
@@ -1912,14 +1959,14 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>
characterLiteral;
-/// \brief Matches integer literals of all sizes / encodings, e.g.
+/// Matches integer literals of all sizes / encodings, e.g.
/// 1, 1L, 0x1 and 1U.
///
/// Does not match character-encoded integers such as L'a'.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
integerLiteral;
-/// \brief Matches float literals of all sizes / encodings, e.g.
+/// Matches float literals of all sizes / encodings, e.g.
/// 1.0, 1.0f, 1.0L and 1e10.
///
/// Does not match implicit conversions such as
@@ -1929,13 +1976,13 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral>
floatLiteral;
-/// \brief Matches user defined literal operator call.
+/// Matches user defined literal operator call.
///
/// Example match: "foo"_suffix
extern const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
userDefinedLiteral;
-/// \brief Matches compound (i.e. non-scalar) literals
+/// Matches compound (i.e. non-scalar) literals
///
/// Example match: {1}, (1, 2)
/// \code
@@ -1945,22 +1992,22 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
compoundLiteralExpr;
-/// \brief Matches nullptr literal.
+/// Matches nullptr literal.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
cxxNullPtrLiteralExpr;
-/// \brief Matches GNU __null expression.
+/// Matches GNU __null expression.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr>
gnuNullExpr;
-/// \brief Matches atomic builtins.
+/// Matches atomic builtins.
/// Example matches __atomic_load_n(ptr, 1)
/// \code
/// void foo() { int *ptr; __atomic_load_n(ptr, 1); }
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
-/// \brief Matches statement expression (GNU extension).
+/// Matches statement expression (GNU extension).
///
/// Example match: ({ int X = 4; X; })
/// \code
@@ -1968,7 +2015,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
-/// \brief Matches binary operator expressions.
+/// Matches binary operator expressions.
///
/// Example matches a || b
/// \code
@@ -1977,7 +2024,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
binaryOperator;
-/// \brief Matches unary operator expressions.
+/// Matches unary operator expressions.
///
/// Example matches !a
/// \code
@@ -1986,7 +2033,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator>
unaryOperator;
-/// \brief Matches conditional operator expressions.
+/// Matches conditional operator expressions.
///
/// Example matches a ? b : c
/// \code
@@ -1995,7 +2042,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator>
conditionalOperator;
-/// \brief Matches binary conditional operator expressions (GNU extension).
+/// Matches binary conditional operator expressions (GNU extension).
///
/// Example matches a ?: b
/// \code
@@ -2005,7 +2052,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt,
BinaryConditionalOperator>
binaryConditionalOperator;
-/// \brief Matches opaque value expressions. They are used as helpers
+/// Matches opaque value expressions. They are used as helpers
/// to reference another expressions and can be met
/// in BinaryConditionalOperators, for example.
///
@@ -2016,7 +2063,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt,
extern const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
opaqueValueExpr;
-/// \brief Matches a C++ static_assert declaration.
+/// Matches a C++ static_assert declaration.
///
/// Example:
/// staticAssertExpr()
@@ -2032,7 +2079,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
extern const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl>
staticAssertDecl;
-/// \brief Matches a reinterpret_cast expression.
+/// Matches a reinterpret_cast expression.
///
/// Either the source expression or the destination type can be matched
/// using has(), but hasDestinationType() is more specific and can be
@@ -2045,7 +2092,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>
cxxReinterpretCastExpr;
-/// \brief Matches a C++ static_cast expression.
+/// Matches a C++ static_cast expression.
///
/// \see hasDestinationType
/// \see reinterpretCast
@@ -2061,7 +2108,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>
cxxStaticCastExpr;
-/// \brief Matches a dynamic_cast expression.
+/// Matches a dynamic_cast expression.
///
/// Example:
/// cxxDynamicCastExpr()
@@ -2076,7 +2123,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>
cxxDynamicCastExpr;
-/// \brief Matches a const_cast expression.
+/// Matches a const_cast expression.
///
/// Example: Matches const_cast<int*>(&r) in
/// \code
@@ -2087,7 +2134,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>
cxxConstCastExpr;
-/// \brief Matches a C-style cast expression.
+/// Matches a C-style cast expression.
///
/// Example: Matches (int) 2.2f in
/// \code
@@ -2096,7 +2143,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr>
cStyleCastExpr;
-/// \brief Matches explicit cast expressions.
+/// Matches explicit cast expressions.
///
/// Matches any cast expression written in user code, whether it be a
/// C-style cast, a functional-style cast, or a keyword cast.
@@ -2120,14 +2167,14 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr>
explicitCastExpr;
-/// \brief Matches the implicit cast nodes of Clang's AST.
+/// Matches the implicit cast nodes of Clang's AST.
///
/// This matches many different places, including function call return value
/// eliding, as well as any type conversions.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>
implicitCastExpr;
-/// \brief Matches any cast nodes of Clang's AST.
+/// Matches any cast nodes of Clang's AST.
///
/// Example: castExpr() matches each of the following:
/// \code
@@ -2142,7 +2189,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
-/// \brief Matches functional cast expressions
+/// Matches functional cast expressions
///
/// Example: Matches Foo(bar);
/// \code
@@ -2153,7 +2200,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr>
cxxFunctionalCastExpr;
-/// \brief Matches functional cast expressions having N != 1 arguments
+/// Matches functional cast expressions having N != 1 arguments
///
/// Example: Matches Foo(bar, bar)
/// \code
@@ -2162,7 +2209,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr>
cxxTemporaryObjectExpr;
-/// \brief Matches predefined identifier expressions [C99 6.4.2.2].
+/// Matches predefined identifier expressions [C99 6.4.2.2].
///
/// Example: Matches __func__
/// \code
@@ -2171,7 +2218,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr>
predefinedExpr;
-/// \brief Matches C99 designated initializer expressions [C99 6.7.8].
+/// Matches C99 designated initializer expressions [C99 6.7.8].
///
/// Example: Matches { [2].y = 1.0, [0].x = 1.0 }
/// \code
@@ -2180,7 +2227,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr>
designatedInitExpr;
-/// \brief Matches designated initializer expressions that contain
+/// Matches designated initializer expressions that contain
/// a specific number of designators.
///
/// Example: Given
@@ -2195,16 +2242,16 @@ AST_MATCHER_P(DesignatedInitExpr, designatorCountIs, unsigned, N) {
return Node.size() == N;
}
-/// \brief Matches \c QualTypes in the clang AST.
+/// Matches \c QualTypes in the clang AST.
extern const internal::VariadicAllOfMatcher<QualType> qualType;
-/// \brief Matches \c Types in the clang AST.
+/// Matches \c Types in the clang AST.
extern const internal::VariadicAllOfMatcher<Type> type;
-/// \brief Matches \c TypeLocs in the clang AST.
+/// Matches \c TypeLocs in the clang AST.
extern const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
-/// \brief Matches if any of the given matchers matches.
+/// Matches if any of the given matchers matches.
///
/// Unlike \c anyOf, \c eachOf will generate a match result for each
/// matching submatcher.
@@ -2227,21 +2274,21 @@ extern const internal::VariadicOperatorMatcherFunc<
2, std::numeric_limits<unsigned>::max()>
eachOf;
-/// \brief Matches if any of the given matchers matches.
+/// Matches if any of the given matchers matches.
///
/// Usable as: Any Matcher
extern const internal::VariadicOperatorMatcherFunc<
2, std::numeric_limits<unsigned>::max()>
anyOf;
-/// \brief Matches if all given matchers match.
+/// Matches if all given matchers match.
///
/// Usable as: Any Matcher
extern const internal::VariadicOperatorMatcherFunc<
2, std::numeric_limits<unsigned>::max()>
allOf;
-/// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
+/// Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
///
/// Given
/// \code
@@ -2254,7 +2301,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt,
UnaryExprOrTypeTraitExpr>
unaryExprOrTypeTraitExpr;
-/// \brief Matches unary expressions that have a specific type of argument.
+/// Matches unary expressions that have a specific type of argument.
///
/// Given
/// \code
@@ -2268,7 +2315,7 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType,
return InnerMatcher.matches(ArgumentType, Finder, Builder);
}
-/// \brief Matches unary expressions of a certain kind.
+/// Matches unary expressions of a certain kind.
///
/// Given
/// \code
@@ -2281,7 +2328,7 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
return Node.getKind() == Kind;
}
-/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
+/// Same as unaryExprOrTypeTraitExpr, but only matching
/// alignof.
inline internal::Matcher<Stmt> alignOfExpr(
const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
@@ -2289,7 +2336,7 @@ inline internal::Matcher<Stmt> alignOfExpr(
ofKind(UETT_AlignOf), InnerMatcher)));
}
-/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
+/// Same as unaryExprOrTypeTraitExpr, but only matching
/// sizeof.
inline internal::Matcher<Stmt> sizeOfExpr(
const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
@@ -2297,7 +2344,7 @@ inline internal::Matcher<Stmt> sizeOfExpr(
allOf(ofKind(UETT_SizeOf), InnerMatcher)));
}
-/// \brief Matches NamedDecl nodes that have the specified name.
+/// Matches NamedDecl nodes that have the specified name.
///
/// Supports specifying enclosing namespaces or classes by prefixing the name
/// with '<enclosing>::'.
@@ -2313,12 +2360,10 @@ inline internal::Matcher<Stmt> sizeOfExpr(
/// namespace a { namespace b { class X; } }
/// \endcode
inline internal::Matcher<NamedDecl> hasName(const std::string &Name) {
- std::vector<std::string> Names;
- Names.push_back(Name);
- return internal::Matcher<NamedDecl>(new internal::HasNameMatcher(Names));
+ return internal::Matcher<NamedDecl>(new internal::HasNameMatcher({Name}));
}
-/// \brief Matches NamedDecl nodes that have any of the specified names.
+/// Matches NamedDecl nodes that have any of the specified names.
///
/// This matcher is only provided as a performance optimization of hasName.
/// \code
@@ -2332,7 +2377,7 @@ extern const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
internal::hasAnyNameFunc>
hasAnyName;
-/// \brief Matches NamedDecl nodes whose fully qualified names contain
+/// Matches NamedDecl nodes whose fully qualified names contain
/// a substring matched by the given RegExp.
///
/// Supports specifying enclosing namespaces or classes by
@@ -2355,7 +2400,7 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
return RE.match(FullNameString);
}
-/// \brief Matches overloaded operator names.
+/// Matches overloaded operator names.
///
/// Matches overloaded operator names specified in strings without the
/// "operator" prefix: e.g. "<<".
@@ -2383,7 +2428,7 @@ hasOverloadedOperatorName(StringRef Name) {
AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>(Name);
}
-/// \brief Matches C++ classes that are directly or indirectly derived from
+/// Matches C++ classes that are directly or indirectly derived from
/// a class matching \c Base.
///
/// Note that a class is not considered to be derived from itself.
@@ -2409,13 +2454,13 @@ AST_MATCHER_P(CXXRecordDecl, isDerivedFrom,
return Finder->classIsDerivedFrom(&Node, Base, Builder);
}
-/// \brief Overloaded method as shortcut for \c isDerivedFrom(hasName(...)).
+/// Overloaded method as shortcut for \c isDerivedFrom(hasName(...)).
AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isDerivedFrom, std::string, BaseName, 1) {
assert(!BaseName.empty());
return isDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder);
}
-/// \brief Similar to \c isDerivedFrom(), but also matches classes that directly
+/// Similar to \c isDerivedFrom(), but also matches classes that directly
/// match \c Base.
AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom,
internal::Matcher<NamedDecl>, Base, 0) {
@@ -2423,7 +2468,7 @@ AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom,
.matches(Node, Finder, Builder);
}
-/// \brief Overloaded method as shortcut for
+/// Overloaded method as shortcut for
/// \c isSameOrDerivedFrom(hasName(...)).
AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, std::string,
BaseName, 1) {
@@ -2431,7 +2476,7 @@ AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, std::string,
return isSameOrDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder);
}
-/// \brief Matches the first method of a class or struct that satisfies \c
+/// Matches the first method of a class or struct that satisfies \c
/// InnerMatcher.
///
/// Given:
@@ -2448,7 +2493,7 @@ AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>,
Node.method_end(), Finder, Builder);
}
-/// \brief Matches the generated class of lambda expressions.
+/// Matches the generated class of lambda expressions.
///
/// Given:
/// \code
@@ -2461,7 +2506,7 @@ AST_MATCHER(CXXRecordDecl, isLambda) {
return Node.isLambda();
}
-/// \brief Matches AST nodes that have child AST nodes that match the
+/// Matches AST nodes that have child AST nodes that match the
/// provided matcher.
///
/// Example matches X, Y
@@ -2481,7 +2526,7 @@ AST_MATCHER(CXXRecordDecl, isLambda) {
/// has(ignoringParenImpCasts(expr())).
extern const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has;
-/// \brief Matches AST nodes that have descendant AST nodes that match the
+/// Matches AST nodes that have descendant AST nodes that match the
/// provided matcher.
///
/// Example matches X, Y, Z
@@ -2499,14 +2544,15 @@ extern const internal::ArgumentAdaptingMatcherFunc<
internal::HasDescendantMatcher>
hasDescendant;
-/// \brief Matches AST nodes that have child AST nodes that match the
+/// Matches AST nodes that have child AST nodes that match the
/// provided matcher.
///
-/// Example matches X, Y
+/// Example matches X, Y, Y::X, Z::Y, Z::Y::X
/// (matcher = cxxRecordDecl(forEach(cxxRecordDecl(hasName("X")))
/// \code
-/// class X {}; // Matches X, because X::X is a class of name X inside X.
-/// class Y { class X {}; };
+/// class X {};
+/// class Y { class X {}; }; // Matches Y, because Y::X is a class of name X
+/// // inside Y.
/// class Z { class Y { class X {}; }; }; // Does not match Z.
/// \endcode
///
@@ -2519,14 +2565,15 @@ extern const internal::ArgumentAdaptingMatcherFunc<
extern const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher>
forEach;
-/// \brief Matches AST nodes that have descendant AST nodes that match the
+/// Matches AST nodes that have descendant AST nodes that match the
/// provided matcher.
///
-/// Example matches X, A, B, C
+/// Example matches X, A, A::X, B, B::C, B::C::X
/// (matcher = cxxRecordDecl(forEachDescendant(cxxRecordDecl(hasName("X")))))
/// \code
-/// class X {}; // Matches X, because X::X is a class of name X inside X.
-/// class A { class X {}; };
+/// class X {};
+/// class A { class X {}; }; // Matches A, because A::X is a class of name
+/// // X inside A.
/// class B { class C { class X {}; }; };
/// \endcode
///
@@ -2549,7 +2596,7 @@ extern const internal::ArgumentAdaptingMatcherFunc<
internal::ForEachDescendantMatcher>
forEachDescendant;
-/// \brief Matches if the node or any descendant matches.
+/// Matches if the node or any descendant matches.
///
/// Generates results for each match.
///
@@ -2570,7 +2617,7 @@ internal::Matcher<T> findAll(const internal::Matcher<T> &Matcher) {
return eachOf(Matcher, forEachDescendant(Matcher));
}
-/// \brief Matches AST nodes that have a parent that matches the provided
+/// Matches AST nodes that have a parent that matches the provided
/// matcher.
///
/// Given
@@ -2586,7 +2633,7 @@ extern const internal::ArgumentAdaptingMatcherFunc<
internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
hasParent;
-/// \brief Matches AST nodes that have an ancestor that matches the provided
+/// Matches AST nodes that have an ancestor that matches the provided
/// matcher.
///
/// Given
@@ -2603,7 +2650,7 @@ extern const internal::ArgumentAdaptingMatcherFunc<
internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
hasAncestor;
-/// \brief Matches if the provided matcher does not match.
+/// Matches if the provided matcher does not match.
///
/// Example matches Y (matcher = cxxRecordDecl(unless(hasName("X"))))
/// \code
@@ -2614,7 +2661,7 @@ extern const internal::ArgumentAdaptingMatcherFunc<
/// Usable as: Any Matcher
extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;
-/// \brief Matches a node if the declaration associated with that node
+/// Matches a node if the declaration associated with that node
/// matches the given matcher.
///
/// The associated declaration is:
@@ -2623,6 +2670,7 @@ extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;
/// - for MemberExpr, the declaration of the referenced member
/// - for CXXConstructExpr, the declaration of the constructor
/// - for CXXNewExpr, the declaration of the operator new
+/// - for ObjCIvarExpr, the declaration of the ivar
///
/// For type nodes, hasDeclaration will generally match the declaration of the
/// sugared type. Given
@@ -2656,7 +2704,7 @@ hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
void(internal::HasDeclarationSupportedTypes)>(InnerMatcher);
}
-/// \brief Matches a \c NamedDecl whose underlying declaration matches the given
+/// Matches a \c NamedDecl whose underlying declaration matches the given
/// matcher.
///
/// Given
@@ -2675,13 +2723,13 @@ AST_MATCHER_P(NamedDecl, hasUnderlyingDecl, internal::Matcher<NamedDecl>,
InnerMatcher.matches(*UnderlyingDecl, Finder, Builder);
}
-/// \brief Matches on the implicit object argument of a member call expression.
+/// Matches on the implicit object argument of a member call expression.
///
/// Example matches y.x()
/// (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y"))))))
/// \code
/// class Y { public: void x(); };
-/// void z() { Y y; y.x(); }",
+/// void z() { Y y; y.x(); }
/// \endcode
///
/// FIXME: Overload to allow directly matching types?
@@ -2694,7 +2742,7 @@ AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,
}
-/// \brief Matches on the receiver of an ObjectiveC Message expression.
+/// Matches on the receiver of an ObjectiveC Message expression.
///
/// Example
/// matcher = objCMessageExpr(hasReceiverType(asString("UIWebView *")));
@@ -2709,8 +2757,43 @@ AST_MATCHER_P(ObjCMessageExpr, hasReceiverType, internal::Matcher<QualType>,
const QualType TypeDecl = Node.getReceiverType();
return InnerMatcher.matches(TypeDecl, Finder, Builder);
}
-
-/// \brief Matches when BaseName == Selector.getAsString()
+
+/// Returns true when the Objective-C message is sent to an instance.
+///
+/// Example
+/// matcher = objcMessagaeExpr(isInstanceMessage())
+/// matches
+/// \code
+/// NSString *x = @"hello";
+/// [x containsString:@"h"];
+/// \endcode
+/// but not
+/// \code
+/// [NSString stringWithFormat:@"format"];
+/// \endcode
+AST_MATCHER(ObjCMessageExpr, isInstanceMessage) {
+ return Node.isInstanceMessage();
+}
+
+/// Matches if the Objective-C message is sent to an instance,
+/// and the inner matcher matches on that instance.
+///
+/// For example the method call in
+/// \code
+/// NSString *x = @"hello";
+/// [x containsString:@"h"];
+/// \endcode
+/// is matched by
+/// objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))
+AST_MATCHER_P(ObjCMessageExpr, hasReceiver, internal::Matcher<Expr>,
+ InnerMatcher) {
+ const Expr *ReceiverNode = Node.getInstanceReceiver();
+ return (ReceiverNode != nullptr &&
+ InnerMatcher.matches(*ReceiverNode->IgnoreParenImpCasts(), Finder,
+ Builder));
+}
+
+/// Matches when BaseName == Selector.getAsString()
///
/// matcher = objCMessageExpr(hasSelector("loadHTMLString:baseURL:"));
/// matches the outer message expr in the code below, but NOT the message
@@ -2723,8 +2806,22 @@ AST_MATCHER_P(ObjCMessageExpr, hasSelector, std::string, BaseName) {
return BaseName.compare(Sel.getAsString()) == 0;
}
-
-/// \brief Matches ObjC selectors whose name contains
+
+/// Matches when at least one of the supplied string equals to the
+/// Selector.getAsString()
+///
+/// matcher = objCMessageExpr(hasSelector("methodA:", "methodB:"));
+/// matches both of the expressions below:
+/// \code
+/// [myObj methodA:argA];
+/// [myObj methodB:argB];
+/// \endcode
+extern const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>,
+ StringRef,
+ internal::hasAnySelectorFunc>
+ hasAnySelector;
+
+/// Matches ObjC selectors whose name contains
/// a substring matched by the given RegExp.
/// matcher = objCMessageExpr(matchesSelector("loadHTMLString\:baseURL?"));
/// matches the outer message expr in the code below, but NOT the message
@@ -2739,7 +2836,7 @@ AST_MATCHER_P(ObjCMessageExpr, matchesSelector, std::string, RegExp) {
return RE.match(SelectorString);
}
-/// \brief Matches when the selector is the empty selector
+/// Matches when the selector is the empty selector
///
/// Matches only when the selector of the objCMessageExpr is NULL. This may
/// represent an error condition in the tree!
@@ -2747,7 +2844,7 @@ AST_MATCHER(ObjCMessageExpr, hasNullSelector) {
return Node.getSelector().isNull();
}
-/// \brief Matches when the selector is a Unary Selector
+/// Matches when the selector is a Unary Selector
///
/// matcher = objCMessageExpr(matchesSelector(hasUnarySelector());
/// matches self.bodyView in the code below, but NOT the outer message
@@ -2759,7 +2856,7 @@ AST_MATCHER(ObjCMessageExpr, hasUnarySelector) {
return Node.getSelector().isUnarySelector();
}
-/// \brief Matches when the selector is a keyword selector
+/// Matches when the selector is a keyword selector
///
/// objCMessageExpr(hasKeywordSelector()) matches the generated setFrame
/// message expression in
@@ -2775,7 +2872,7 @@ AST_MATCHER(ObjCMessageExpr, hasKeywordSelector) {
return Node.getSelector().isKeywordSelector();
}
-/// \brief Matches when the selector has the specified number of arguments
+/// Matches when the selector has the specified number of arguments
///
/// matcher = objCMessageExpr(numSelectorArgs(0));
/// matches self.bodyView in the code below
@@ -2790,7 +2887,7 @@ AST_MATCHER_P(ObjCMessageExpr, numSelectorArgs, unsigned, N) {
return Node.getSelector().getNumArgs() == N;
}
-/// \brief Matches if the call expression's callee expression matches.
+/// Matches if the call expression's callee expression matches.
///
/// Given
/// \code
@@ -2813,7 +2910,7 @@ AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
InnerMatcher.matches(*ExprNode, Finder, Builder));
}
-/// \brief Matches if the call expression's callee's declaration matches the
+/// Matches if the call expression's callee's declaration matches the
/// given matcher.
///
/// Example matches y.x() (matcher = callExpr(callee(
@@ -2827,25 +2924,31 @@ AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher,
return callExpr(hasDeclaration(InnerMatcher)).matches(Node, Finder, Builder);
}
-/// \brief Matches if the expression's or declaration's type matches a type
+/// Matches if the expression's or declaration's type matches a type
/// matcher.
///
/// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
/// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
/// and U (matcher = typedefDecl(hasType(asString("int")))
+/// and friend class X (matcher = friendDecl(hasType("X"))
/// \code
/// class X {};
/// void y(X &x) { x; X z; }
/// typedef int U;
+/// class Y { friend class X; };
/// \endcode
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
- hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, TypedefNameDecl, ValueDecl),
+ hasType,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, FriendDecl, TypedefNameDecl,
+ ValueDecl),
internal::Matcher<QualType>, InnerMatcher, 0) {
- return InnerMatcher.matches(internal::getUnderlyingType(Node),
- Finder, Builder);
+ QualType QT = internal::getUnderlyingType(Node);
+ if (!QT.isNull())
+ return InnerMatcher.matches(QT, Finder, Builder);
+ return false;
}
-/// \brief Overloaded to match the declaration of the expression's or value
+/// Overloaded to match the declaration of the expression's or value
/// declaration's type.
///
/// In case of a value declaration (for example a variable declaration),
@@ -2856,21 +2959,24 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
///
/// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
/// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+/// and friend class X (matcher = friendDecl(hasType("X"))
/// \code
/// class X {};
/// void y(X &x) { x; X z; }
+/// class Y { friend class X; };
/// \endcode
///
/// Usable as: Matcher<Expr>, Matcher<ValueDecl>
-AST_POLYMORPHIC_MATCHER_P_OVERLOAD(hasType,
- AST_POLYMORPHIC_SUPPORTED_TYPES(Expr,
- ValueDecl),
- internal::Matcher<Decl>, InnerMatcher, 1) {
- return qualType(hasDeclaration(InnerMatcher))
- .matches(Node.getType(), Finder, Builder);
+AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
+ hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, FriendDecl, ValueDecl),
+ internal::Matcher<Decl>, InnerMatcher, 1) {
+ QualType QT = internal::getUnderlyingType(Node);
+ if (!QT.isNull())
+ return qualType(hasDeclaration(InnerMatcher)).matches(QT, Finder, Builder);
+ return false;
}
-/// \brief Matches if the type location of the declarator decl's type matches
+/// Matches if the type location of the declarator decl's type matches
/// the inner matcher.
///
/// Given
@@ -2886,7 +2992,7 @@ AST_MATCHER_P(DeclaratorDecl, hasTypeLoc, internal::Matcher<TypeLoc>, Inner) {
return Inner.matches(Node.getTypeSourceInfo()->getTypeLoc(), Finder, Builder);
}
-/// \brief Matches if the matched type is represented by the given string.
+/// Matches if the matched type is represented by the given string.
///
/// Given
/// \code
@@ -2899,7 +3005,7 @@ AST_MATCHER_P(QualType, asString, std::string, Name) {
return Name == Node.getAsString();
}
-/// \brief Matches if the matched type is a pointer type and the pointee type
+/// Matches if the matched type is a pointer type and the pointee type
/// matches the specified matcher.
///
/// Example matches y->x()
@@ -2916,14 +3022,14 @@ AST_MATCHER_P(
InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
}
-/// \brief Overloaded to match the pointee type's declaration.
+/// Overloaded to match the pointee type's declaration.
AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>,
InnerMatcher, 1) {
return pointsTo(qualType(hasDeclaration(InnerMatcher)))
.matches(Node, Finder, Builder);
}
-/// \brief Matches if the matched type matches the unqualified desugared
+/// Matches if the matched type matches the unqualified desugared
/// type of the matched node.
///
/// For example, in:
@@ -2931,7 +3037,7 @@ AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>,
/// class A {};
/// using B = A;
/// \endcode
-/// The matcher type(hasUnqualifeidDesugaredType(recordType())) matches
+/// The matcher type(hasUnqualifiedDesugaredType(recordType())) matches
/// both B and A.
AST_MATCHER_P(Type, hasUnqualifiedDesugaredType, internal::Matcher<Type>,
InnerMatcher) {
@@ -2939,7 +3045,7 @@ AST_MATCHER_P(Type, hasUnqualifiedDesugaredType, internal::Matcher<Type>,
Builder);
}
-/// \brief Matches if the matched type is a reference type and the referenced
+/// Matches if the matched type is a reference type and the referenced
/// type matches the specified matcher.
///
/// Example matches X &x and const X &y
@@ -2958,7 +3064,7 @@ AST_MATCHER_P(QualType, references, internal::Matcher<QualType>,
InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
}
-/// \brief Matches QualTypes whose canonical type matches InnerMatcher.
+/// Matches QualTypes whose canonical type matches InnerMatcher.
///
/// Given:
/// \code
@@ -2977,7 +3083,7 @@ AST_MATCHER_P(QualType, hasCanonicalType, internal::Matcher<QualType>,
return InnerMatcher.matches(Node.getCanonicalType(), Finder, Builder);
}
-/// \brief Overloaded to match the referenced type's declaration.
+/// Overloaded to match the referenced type's declaration.
AST_MATCHER_P_OVERLOAD(QualType, references, internal::Matcher<Decl>,
InnerMatcher, 1) {
return references(qualType(hasDeclaration(InnerMatcher)))
@@ -2991,7 +3097,7 @@ AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
InnerMatcher.matches(*ExprNode, Finder, Builder));
}
-/// \brief Matches if the expression's type either matches the specified
+/// Matches if the expression's type either matches the specified
/// matcher, or is a pointer to a type that matches the InnerMatcher.
AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
internal::Matcher<QualType>, InnerMatcher, 0) {
@@ -3000,7 +3106,7 @@ AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
.matches(Node, Finder, Builder);
}
-/// \brief Overloaded to match the type's declaration.
+/// Overloaded to match the type's declaration.
AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
internal::Matcher<Decl>, InnerMatcher, 1) {
return onImplicitObjectArgument(
@@ -3008,7 +3114,7 @@ AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
.matches(Node, Finder, Builder);
}
-/// \brief Matches a DeclRefExpr that refers to a declaration that matches the
+/// Matches a DeclRefExpr that refers to a declaration that matches the
/// specified matcher.
///
/// Example matches x in if(x)
@@ -3024,7 +3130,7 @@ AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
InnerMatcher.matches(*DeclNode, Finder, Builder));
}
-/// \brief Matches a \c DeclRefExpr that refers to a declaration through a
+/// Matches a \c DeclRefExpr that refers to a declaration through a
/// specific using shadow declaration.
///
/// Given
@@ -3046,7 +3152,7 @@ AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
return false;
}
-/// \brief Matches an \c OverloadExpr if any of the declarations in the set of
+/// Matches an \c OverloadExpr if any of the declarations in the set of
/// overloads matches the given matcher.
///
/// Given
@@ -3067,7 +3173,7 @@ AST_MATCHER_P(OverloadExpr, hasAnyDeclaration, internal::Matcher<Decl>,
Node.decls_end(), Finder, Builder);
}
-/// \brief Matches the Decl of a DeclStmt which has a single declaration.
+/// Matches the Decl of a DeclStmt which has a single declaration.
///
/// Given
/// \code
@@ -3084,7 +3190,7 @@ AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher<Decl>, InnerMatcher) {
return false;
}
-/// \brief Matches a variable declaration that has an initializer expression
+/// Matches a variable declaration that has an initializer expression
/// that matches the given matcher.
///
/// Example matches x (matcher = varDecl(hasInitializer(callExpr())))
@@ -3100,7 +3206,7 @@ AST_MATCHER_P(
InnerMatcher.matches(*Initializer, Finder, Builder));
}
-/// \brief Matches a variable declaration that has function scope and is a
+/// Matches a variable declaration that has function scope and is a
/// non-static local variable.
///
/// Example matches x (matcher = varDecl(hasLocalStorage())
@@ -3115,7 +3221,7 @@ AST_MATCHER(VarDecl, hasLocalStorage) {
return Node.hasLocalStorage();
}
-/// \brief Matches a variable declaration that does not have local storage.
+/// Matches a variable declaration that does not have local storage.
///
/// Example matches y and z (matcher = varDecl(hasGlobalStorage())
/// \code
@@ -3129,7 +3235,7 @@ AST_MATCHER(VarDecl, hasGlobalStorage) {
return Node.hasGlobalStorage();
}
-/// \brief Matches a variable declaration that has automatic storage duration.
+/// Matches a variable declaration that has automatic storage duration.
///
/// Example matches x, but not y, z, or a.
/// (matcher = varDecl(hasAutomaticStorageDuration())
@@ -3145,7 +3251,7 @@ AST_MATCHER(VarDecl, hasAutomaticStorageDuration) {
return Node.getStorageDuration() == SD_Automatic;
}
-/// \brief Matches a variable declaration that has static storage duration.
+/// Matches a variable declaration that has static storage duration.
/// It includes the variable declared at namespace scope and those declared
/// with "static" and "extern" storage class specifiers.
///
@@ -3165,7 +3271,7 @@ AST_MATCHER(VarDecl, hasStaticStorageDuration) {
return Node.getStorageDuration() == SD_Static;
}
-/// \brief Matches a variable declaration that has thread storage duration.
+/// Matches a variable declaration that has thread storage duration.
///
/// Example matches z, but not x, z, or a.
/// (matcher = varDecl(hasThreadStorageDuration())
@@ -3181,7 +3287,7 @@ AST_MATCHER(VarDecl, hasThreadStorageDuration) {
return Node.getStorageDuration() == SD_Thread;
}
-/// \brief Matches a variable declaration that is an exception variable from
+/// Matches a variable declaration that is an exception variable from
/// a C++ catch block, or an Objective-C \@catch statement.
///
/// Example matches x (matcher = varDecl(isExceptionVariable())
@@ -3196,7 +3302,7 @@ AST_MATCHER(VarDecl, isExceptionVariable) {
return Node.isExceptionVariable();
}
-/// \brief Checks that a call expression or a constructor call expression has
+/// Checks that a call expression or a constructor call expression has
/// a specific number of arguments (including absent default arguments).
///
/// Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2)))
@@ -3212,7 +3318,7 @@ AST_POLYMORPHIC_MATCHER_P(argumentCountIs,
return Node.getNumArgs() == N;
}
-/// \brief Matches the n'th argument of a call expression or a constructor
+/// Matches the n'th argument of a call expression or a constructor
/// call expression.
///
/// Example matches y in x(y)
@@ -3230,7 +3336,7 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument,
*Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
}
-/// \brief Matches declaration statements that contain a specific number of
+/// Matches declaration statements that contain a specific number of
/// declarations.
///
/// Example: Given
@@ -3245,7 +3351,7 @@ AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N) {
return std::distance(Node.decl_begin(), Node.decl_end()) == (ptrdiff_t)N;
}
-/// \brief Matches the n'th declaration of a declaration statement.
+/// Matches the n'th declaration of a declaration statement.
///
/// Note that this does not work for global declarations because the AST
/// breaks up multiple-declaration DeclStmt's into multiple single-declaration
@@ -3274,7 +3380,7 @@ AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N,
return InnerMatcher.matches(**Iterator, Finder, Builder);
}
-/// \brief Matches a C++ catch statement that has a catch-all handler.
+/// Matches a C++ catch statement that has a catch-all handler.
///
/// Given
/// \code
@@ -3291,7 +3397,7 @@ AST_MATCHER(CXXCatchStmt, isCatchAll) {
return Node.getExceptionDecl() == nullptr;
}
-/// \brief Matches a constructor initializer.
+/// Matches a constructor initializer.
///
/// Given
/// \code
@@ -3310,7 +3416,7 @@ AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,
Node.init_end(), Finder, Builder);
}
-/// \brief Matches the field declaration of a constructor initializer.
+/// Matches the field declaration of a constructor initializer.
///
/// Given
/// \code
@@ -3330,7 +3436,7 @@ AST_MATCHER_P(CXXCtorInitializer, forField,
InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
}
-/// \brief Matches the initializer expression of a constructor initializer.
+/// Matches the initializer expression of a constructor initializer.
///
/// Given
/// \code
@@ -3350,7 +3456,7 @@ AST_MATCHER_P(CXXCtorInitializer, withInitializer,
InnerMatcher.matches(*NodeAsExpr, Finder, Builder));
}
-/// \brief Matches a constructor initializer if it is explicitly written in
+/// Matches a constructor initializer if it is explicitly written in
/// code (as opposed to implicitly added by the compiler).
///
/// Given
@@ -3367,7 +3473,7 @@ AST_MATCHER(CXXCtorInitializer, isWritten) {
return Node.isWritten();
}
-/// \brief Matches a constructor initializer if it is initializing a base, as
+/// Matches a constructor initializer if it is initializing a base, as
/// opposed to a member.
///
/// Given
@@ -3387,7 +3493,7 @@ AST_MATCHER(CXXCtorInitializer, isBaseInitializer) {
return Node.isBaseInitializer();
}
-/// \brief Matches a constructor initializer if it is initializing a member, as
+/// Matches a constructor initializer if it is initializing a member, as
/// opposed to a base.
///
/// Given
@@ -3407,8 +3513,8 @@ AST_MATCHER(CXXCtorInitializer, isMemberInitializer) {
return Node.isMemberInitializer();
}
-/// \brief Matches any argument of a call expression or a constructor call
-/// expression.
+/// Matches any argument of a call expression or a constructor call
+/// expression, or an ObjC-message-send expression.
///
/// Given
/// \code
@@ -3418,9 +3524,18 @@ AST_MATCHER(CXXCtorInitializer, isMemberInitializer) {
/// matches x(1, y, 42)
/// with hasAnyArgument(...)
/// matching y
+///
+/// For ObjectiveC, given
+/// \code
+/// @interface I - (void) f:(int) y; @end
+/// void foo(I *i) { [i f:12]; }
+/// \endcode
+/// objcMessageExpr(hasAnyArgument(integerLiteral(equals(12))))
+/// matches [i f:12]
AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
- CXXConstructExpr),
+ CXXConstructExpr,
+ ObjCMessageExpr),
internal::Matcher<Expr>, InnerMatcher) {
for (const Expr *Arg : Node.arguments()) {
BoundNodesTreeBuilder Result(*Builder);
@@ -3432,12 +3547,12 @@ AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
return false;
}
-/// \brief Matches a constructor call expression which uses list initialization.
+/// Matches a constructor call expression which uses list initialization.
AST_MATCHER(CXXConstructExpr, isListInitialization) {
return Node.isListInitialization();
}
-/// \brief Matches a constructor call expression which requires
+/// Matches a constructor call expression which requires
/// zero initialization.
///
/// Given
@@ -3453,7 +3568,8 @@ AST_MATCHER(CXXConstructExpr, requiresZeroInitialization) {
return Node.requiresZeroInitialization();
}
-/// \brief Matches the n'th parameter of a function declaration.
+/// Matches the n'th parameter of a function or an ObjC method
+/// declaration or a block.
///
/// Given
/// \code
@@ -3463,15 +3579,26 @@ AST_MATCHER(CXXConstructExpr, requiresZeroInitialization) {
/// matches f(int x) {}
/// with hasParameter(...)
/// matching int x
-AST_MATCHER_P2(FunctionDecl, hasParameter,
- unsigned, N, internal::Matcher<ParmVarDecl>,
- InnerMatcher) {
- return (N < Node.getNumParams() &&
- InnerMatcher.matches(
- *Node.getParamDecl(N), Finder, Builder));
+///
+/// For ObjectiveC, given
+/// \code
+/// @interface I - (void) f:(int) y; @end
+/// \endcode
+//
+/// the matcher objcMethodDecl(hasParameter(0, hasName("y")))
+/// matches the declaration of method f with hasParameter
+/// matching y.
+AST_POLYMORPHIC_MATCHER_P2(hasParameter,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+ ObjCMethodDecl,
+ BlockDecl),
+ unsigned, N, internal::Matcher<ParmVarDecl>,
+ InnerMatcher) {
+ return (N < Node.parameters().size()
+ && InnerMatcher.matches(*Node.parameters()[N], Finder, Builder));
}
-/// \brief Matches all arguments and their respective ParmVarDecl.
+/// Matches all arguments and their respective ParmVarDecl.
///
/// Given
/// \code
@@ -3525,7 +3652,8 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam,
return Matched;
}
-/// \brief Matches any parameter of a function declaration.
+/// Matches any parameter of a function or an ObjC method declaration or a
+/// block.
///
/// Does not match the 'this' parameter of a method.
///
@@ -3537,13 +3665,35 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam,
/// matches f(int x, int y, int z) {}
/// with hasAnyParameter(...)
/// matching int y
-AST_MATCHER_P(FunctionDecl, hasAnyParameter,
- internal::Matcher<ParmVarDecl>, InnerMatcher) {
+///
+/// For ObjectiveC, given
+/// \code
+/// @interface I - (void) f:(int) y; @end
+/// \endcode
+//
+/// the matcher objcMethodDecl(hasAnyParameter(hasName("y")))
+/// matches the declaration of method f with hasParameter
+/// matching y.
+///
+/// For blocks, given
+/// \code
+/// b = ^(int y) { printf("%d", y) };
+/// \endcode
+///
+/// the matcher blockDecl(hasAnyParameter(hasName("y")))
+/// matches the declaration of the block b with hasParameter
+/// matching y.
+AST_POLYMORPHIC_MATCHER_P(hasAnyParameter,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+ ObjCMethodDecl,
+ BlockDecl),
+ internal::Matcher<ParmVarDecl>,
+ InnerMatcher) {
return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(),
Node.param_end(), Finder, Builder);
}
-/// \brief Matches \c FunctionDecls and \c FunctionProtoTypes that have a
+/// Matches \c FunctionDecls and \c FunctionProtoTypes that have a
/// specific parameter count.
///
/// Given
@@ -3555,11 +3705,11 @@ AST_MATCHER_P(FunctionDecl, hasAnyParameter,
/// void k(int x, int y, int z, ...);
/// \endcode
/// functionDecl(parameterCountIs(2))
-/// matches void g(int i, int j) {}
+/// matches \c g and \c h
/// functionProtoType(parameterCountIs(2))
-/// matches void h(int i, int j)
+/// matches \c g and \c h
/// functionProtoType(parameterCountIs(3))
-/// matches void k(int x, int y, int z, ...);
+/// matches \c k
AST_POLYMORPHIC_MATCHER_P(parameterCountIs,
AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
FunctionProtoType),
@@ -3567,7 +3717,23 @@ AST_POLYMORPHIC_MATCHER_P(parameterCountIs,
return Node.getNumParams() == N;
}
-/// \brief Matches the return type of a function declaration.
+/// Matches \c FunctionDecls that have a noreturn attribute.
+///
+/// Given
+/// \code
+/// void nope();
+/// [[noreturn]] void a();
+/// __attribute__((noreturn)) void b();
+/// struct c { [[noreturn]] c(); };
+/// \endcode
+/// functionDecl(isNoReturn())
+/// matches all of those except
+/// \code
+/// void nope();
+/// \endcode
+AST_MATCHER(FunctionDecl, isNoReturn) { return Node.isNoReturn(); }
+
+/// Matches the return type of a function declaration.
///
/// Given:
/// \code
@@ -3580,7 +3746,7 @@ AST_MATCHER_P(FunctionDecl, returns,
return InnerMatcher.matches(Node.getReturnType(), Finder, Builder);
}
-/// \brief Matches extern "C" function or variable declarations.
+/// Matches extern "C" function or variable declarations.
///
/// Given:
/// \code
@@ -3600,7 +3766,7 @@ AST_POLYMORPHIC_MATCHER(isExternC, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
return Node.isExternC();
}
-/// \brief Matches variable/function declarations that have "static" storage
+/// Matches variable/function declarations that have "static" storage
/// class specifier ("static" keyword) written in the source.
///
/// Given:
@@ -3620,7 +3786,7 @@ AST_POLYMORPHIC_MATCHER(isStaticStorageClass,
return Node.getStorageClass() == SC_Static;
}
-/// \brief Matches deleted function declarations.
+/// Matches deleted function declarations.
///
/// Given:
/// \code
@@ -3633,7 +3799,7 @@ AST_MATCHER(FunctionDecl, isDeleted) {
return Node.isDeleted();
}
-/// \brief Matches defaulted function declarations.
+/// Matches defaulted function declarations.
///
/// Given:
/// \code
@@ -3646,7 +3812,7 @@ AST_MATCHER(FunctionDecl, isDefaulted) {
return Node.isDefaulted();
}
-/// \brief Matches functions that have a dynamic exception specification.
+/// Matches functions that have a dynamic exception specification.
///
/// Given:
/// \code
@@ -3669,7 +3835,7 @@ AST_POLYMORPHIC_MATCHER(hasDynamicExceptionSpec,
return false;
}
-/// \brief Matches functions that have a non-throwing exception specification.
+/// Matches functions that have a non-throwing exception specification.
///
/// Given:
/// \code
@@ -3696,27 +3862,32 @@ AST_POLYMORPHIC_MATCHER(isNoThrow,
if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType()))
return true;
- return FnTy->isNothrow(Finder->getASTContext());
+ return FnTy->isNothrow();
}
-/// \brief Matches constexpr variable and function declarations.
+/// Matches constexpr variable and function declarations,
+/// and if constexpr.
///
/// Given:
/// \code
/// constexpr int foo = 42;
/// constexpr int bar();
+/// void baz() { if constexpr(1 > 0) {} }
/// \endcode
/// varDecl(isConstexpr())
/// matches the declaration of foo.
/// functionDecl(isConstexpr())
/// matches the declaration of bar.
+/// ifStmt(isConstexpr())
+/// matches the if statement in baz.
AST_POLYMORPHIC_MATCHER(isConstexpr,
AST_POLYMORPHIC_SUPPORTED_TYPES(VarDecl,
- FunctionDecl)) {
+ FunctionDecl,
+ IfStmt)) {
return Node.isConstexpr();
}
-/// \brief Matches the condition expression of an if statement, for loop,
+/// Matches the condition expression of an if statement, for loop,
/// switch statement or conditional operator.
///
/// Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
@@ -3733,7 +3904,7 @@ AST_POLYMORPHIC_MATCHER_P(
InnerMatcher.matches(*Condition, Finder, Builder));
}
-/// \brief Matches the then-statement of an if statement.
+/// Matches the then-statement of an if statement.
///
/// Examples matches the if statement
/// (matcher = ifStmt(hasThen(cxxBoolLiteral(equals(true)))))
@@ -3745,7 +3916,7 @@ AST_MATCHER_P(IfStmt, hasThen, internal::Matcher<Stmt>, InnerMatcher) {
return (Then != nullptr && InnerMatcher.matches(*Then, Finder, Builder));
}
-/// \brief Matches the else-statement of an if statement.
+/// Matches the else-statement of an if statement.
///
/// Examples matches the if statement
/// (matcher = ifStmt(hasElse(cxxBoolLiteral(equals(true)))))
@@ -3757,7 +3928,7 @@ AST_MATCHER_P(IfStmt, hasElse, internal::Matcher<Stmt>, InnerMatcher) {
return (Else != nullptr && InnerMatcher.matches(*Else, Finder, Builder));
}
-/// \brief Matches if a node equals a previously bound node.
+/// Matches if a node equals a previously bound node.
///
/// Matches a node if it equals the node previously bound to \p ID.
///
@@ -3794,7 +3965,7 @@ AST_POLYMORPHIC_MATCHER_P(equalsBoundNode,
return Builder->removeBindings(Predicate);
}
-/// \brief Matches the condition variable statement in an if statement.
+/// Matches the condition variable statement in an if statement.
///
/// Given
/// \code
@@ -3810,7 +3981,7 @@ AST_MATCHER_P(IfStmt, hasConditionVariableStatement,
InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
}
-/// \brief Matches the index expression of an array subscript expression.
+/// Matches the index expression of an array subscript expression.
///
/// Given
/// \code
@@ -3826,7 +3997,7 @@ AST_MATCHER_P(ArraySubscriptExpr, hasIndex,
return false;
}
-/// \brief Matches the base expression of an array subscript expression.
+/// Matches the base expression of an array subscript expression.
///
/// Given
/// \code
@@ -3843,7 +4014,7 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase,
return false;
}
-/// \brief Matches a 'for', 'while', 'do while' statement or a function
+/// Matches a 'for', 'while', 'do while' statement or a function
/// definition that has a given body.
///
/// Given
@@ -3865,7 +4036,7 @@ AST_POLYMORPHIC_MATCHER_P(hasBody,
InnerMatcher.matches(*Statement, Finder, Builder));
}
-/// \brief Matches compound statements where at least one substatement matches
+/// Matches compound statements where at least one substatement matches
/// a given matcher. Also matches StmtExprs that have CompoundStmt as children.
///
/// Given
@@ -3885,7 +4056,7 @@ AST_POLYMORPHIC_MATCHER_P(hasAnySubstatement,
CS->body_end(), Finder, Builder);
}
-/// \brief Checks that a compound statement contains a specific number of
+/// Checks that a compound statement contains a specific number of
/// child statements.
///
/// Example: Given
@@ -3899,7 +4070,7 @@ AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) {
return Node.size() == N;
}
-/// \brief Matches literals that are equal to the given value of type ValueT.
+/// Matches literals that are equal to the given value of type ValueT.
///
/// Given
/// \code
@@ -3960,7 +4131,7 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
.matchesNode(Node);
}
-/// \brief Matches the operator Name of operator expressions (binary or
+/// Matches the operator Name of operator expressions (binary or
/// unary).
///
/// Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
@@ -3974,7 +4145,27 @@ AST_POLYMORPHIC_MATCHER_P(hasOperatorName,
return Name == Node.getOpcodeStr(Node.getOpcode());
}
-/// \brief Matches the left hand side of binary operator expressions.
+/// Matches all kinds of assignment operators.
+///
+/// Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator()))
+/// \code
+/// if (a == b)
+/// a += b;
+/// \endcode
+///
+/// Example 2: matches s1 = s2
+/// (matcher = cxxOperatorCallExpr(isAssignmentOperator()))
+/// \code
+/// struct S { S& operator=(const S&); };
+/// void x() { S s1, s2; s1 = s2; })
+/// \endcode
+AST_POLYMORPHIC_MATCHER(isAssignmentOperator,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
+ CXXOperatorCallExpr)) {
+ return Node.isAssignmentOp();
+}
+
+/// Matches the left hand side of binary operator expressions.
///
/// Example matches a (matcher = binaryOperator(hasLHS()))
/// \code
@@ -3989,7 +4180,7 @@ AST_POLYMORPHIC_MATCHER_P(hasLHS,
InnerMatcher.matches(*LeftHandSide, Finder, Builder));
}
-/// \brief Matches the right hand side of binary operator expressions.
+/// Matches the right hand side of binary operator expressions.
///
/// Example matches b (matcher = binaryOperator(hasRHS()))
/// \code
@@ -4004,14 +4195,14 @@ AST_POLYMORPHIC_MATCHER_P(hasRHS,
InnerMatcher.matches(*RightHandSide, Finder, Builder));
}
-/// \brief Matches if either the left hand side or the right hand side of a
+/// Matches if either the left hand side or the right hand side of a
/// binary operator matches.
inline internal::Matcher<BinaryOperator> hasEitherOperand(
const internal::Matcher<Expr> &InnerMatcher) {
return anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher));
}
-/// \brief Matches if the operand of a unary operator matches.
+/// Matches if the operand of a unary operator matches.
///
/// Example matches true (matcher = hasUnaryOperand(
/// cxxBoolLiteral(equals(true))))
@@ -4025,7 +4216,7 @@ AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
InnerMatcher.matches(*Operand, Finder, Builder));
}
-/// \brief Matches if the cast's source expression
+/// Matches if the cast's source expression
/// or opaque value's source expression matches the given matcher.
///
/// Example 1: matches "a string"
@@ -4050,7 +4241,7 @@ AST_POLYMORPHIC_MATCHER_P(hasSourceExpression,
InnerMatcher.matches(*SubExpression, Finder, Builder));
}
-/// \brief Matches casts that has a given cast kind.
+/// Matches casts that has a given cast kind.
///
/// Example: matches the implicit cast around \c 0
/// (matcher = castExpr(hasCastKind(CK_NullToPointer)))
@@ -4061,7 +4252,7 @@ AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
return Node.getCastKind() == Kind;
}
-/// \brief Matches casts whose destination type matches a given matcher.
+/// Matches casts whose destination type matches a given matcher.
///
/// (Note: Clang's AST refers to other conversions as "casts" too, and calls
/// actual casts "explicit" casts.)
@@ -4071,7 +4262,7 @@ AST_MATCHER_P(ExplicitCastExpr, hasDestinationType,
return InnerMatcher.matches(NodeType, Finder, Builder);
}
-/// \brief Matches implicit casts whose destination type matches a given
+/// Matches implicit casts whose destination type matches a given
/// matcher.
///
/// FIXME: Unit test this matcher
@@ -4080,7 +4271,7 @@ AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType,
return InnerMatcher.matches(Node.getType(), Finder, Builder);
}
-/// \brief Matches RecordDecl object that are spelled with "struct."
+/// Matches RecordDecl object that are spelled with "struct."
///
/// Example matches S, but not C or U.
/// \code
@@ -4092,7 +4283,7 @@ AST_MATCHER(RecordDecl, isStruct) {
return Node.isStruct();
}
-/// \brief Matches RecordDecl object that are spelled with "union."
+/// Matches RecordDecl object that are spelled with "union."
///
/// Example matches U, but not C or S.
/// \code
@@ -4104,7 +4295,7 @@ AST_MATCHER(RecordDecl, isUnion) {
return Node.isUnion();
}
-/// \brief Matches RecordDecl object that are spelled with "class."
+/// Matches RecordDecl object that are spelled with "class."
///
/// Example matches C, but not S or U.
/// \code
@@ -4116,7 +4307,7 @@ AST_MATCHER(RecordDecl, isClass) {
return Node.isClass();
}
-/// \brief Matches the true branch expression of a conditional operator.
+/// Matches the true branch expression of a conditional operator.
///
/// Example 1 (conditional ternary operator): matches a
/// \code
@@ -4134,7 +4325,7 @@ AST_MATCHER_P(AbstractConditionalOperator, hasTrueExpression,
InnerMatcher.matches(*Expression, Finder, Builder));
}
-/// \brief Matches the false branch expression of a conditional operator
+/// Matches the false branch expression of a conditional operator
/// (binary or ternary).
///
/// Example matches b
@@ -4149,7 +4340,7 @@ AST_MATCHER_P(AbstractConditionalOperator, hasFalseExpression,
InnerMatcher.matches(*Expression, Finder, Builder));
}
-/// \brief Matches if a declaration has a body attached.
+/// Matches if a declaration has a body attached.
///
/// Example matches A, va, fa
/// \code
@@ -4176,7 +4367,7 @@ AST_POLYMORPHIC_MATCHER(isDefinition,
return Node.isThisDeclarationADefinition();
}
-/// \brief Matches if a function declaration is variadic.
+/// Matches if a function declaration is variadic.
///
/// Example matches f, but not g or h. The function i will not match, even when
/// compiled in C mode.
@@ -4190,7 +4381,7 @@ AST_MATCHER(FunctionDecl, isVariadic) {
return Node.isVariadic();
}
-/// \brief Matches the class declaration that the given method declaration
+/// Matches the class declaration that the given method declaration
/// belongs to.
///
/// FIXME: Generalize this for other kinds of declarations.
@@ -4214,7 +4405,7 @@ AST_MATCHER_P(CXXMethodDecl, ofClass,
InnerMatcher.matches(*Parent, Finder, Builder));
}
-/// \brief Matches each method overriden by the given method. This matcher may
+/// Matches each method overridden by the given method. This matcher may
/// produce multiple matches.
///
/// Given
@@ -4255,7 +4446,7 @@ AST_MATCHER_P(CXXMethodDecl, forEachOverridden,
return Matched;
}
-/// \brief Matches if the given method declaration is virtual.
+/// Matches if the given method declaration is virtual.
///
/// Given
/// \code
@@ -4269,7 +4460,7 @@ AST_MATCHER(CXXMethodDecl, isVirtual) {
return Node.isVirtual();
}
-/// \brief Matches if the given method declaration has an explicit "virtual".
+/// Matches if the given method declaration has an explicit "virtual".
///
/// Given
/// \code
@@ -4287,7 +4478,7 @@ AST_MATCHER(CXXMethodDecl, isVirtualAsWritten) {
return Node.isVirtualAsWritten();
}
-/// \brief Matches if the given method or class declaration is final.
+/// Matches if the given method or class declaration is final.
///
/// Given:
/// \code
@@ -4308,7 +4499,7 @@ AST_POLYMORPHIC_MATCHER(isFinal,
return Node.template hasAttr<FinalAttr>();
}
-/// \brief Matches if the given method declaration is pure.
+/// Matches if the given method declaration is pure.
///
/// Given
/// \code
@@ -4322,7 +4513,7 @@ AST_MATCHER(CXXMethodDecl, isPure) {
return Node.isPure();
}
-/// \brief Matches if the given method declaration is const.
+/// Matches if the given method declaration is const.
///
/// Given
/// \code
@@ -4337,7 +4528,7 @@ AST_MATCHER(CXXMethodDecl, isConst) {
return Node.isConst();
}
-/// \brief Matches if the given method declaration declares a copy assignment
+/// Matches if the given method declaration declares a copy assignment
/// operator.
///
/// Given
@@ -4354,7 +4545,7 @@ AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator) {
return Node.isCopyAssignmentOperator();
}
-/// \brief Matches if the given method declaration declares a move assignment
+/// Matches if the given method declaration declares a move assignment
/// operator.
///
/// Given
@@ -4371,7 +4562,7 @@ AST_MATCHER(CXXMethodDecl, isMoveAssignmentOperator) {
return Node.isMoveAssignmentOperator();
}
-/// \brief Matches if the given method declaration overrides another method.
+/// Matches if the given method declaration overrides another method.
///
/// Given
/// \code
@@ -4389,7 +4580,7 @@ AST_MATCHER(CXXMethodDecl, isOverride) {
return Node.size_overridden_methods() > 0 || Node.hasAttr<OverrideAttr>();
}
-/// \brief Matches method declarations that are user-provided.
+/// Matches method declarations that are user-provided.
///
/// Given
/// \code
@@ -4404,7 +4595,7 @@ AST_MATCHER(CXXMethodDecl, isUserProvided) {
return Node.isUserProvided();
}
-/// \brief Matches member expressions that are called with '->' as opposed
+/// Matches member expressions that are called with '->' as opposed
/// to '.'.
///
/// Member calls on the implicit this pointer match as called with '->'.
@@ -4423,7 +4614,7 @@ AST_MATCHER(MemberExpr, isArrow) {
return Node.isArrow();
}
-/// \brief Matches QualType nodes that are of integer type.
+/// Matches QualType nodes that are of integer type.
///
/// Given
/// \code
@@ -4437,7 +4628,7 @@ AST_MATCHER(QualType, isInteger) {
return Node->isIntegerType();
}
-/// \brief Matches QualType nodes that are of unsigned integer type.
+/// Matches QualType nodes that are of unsigned integer type.
///
/// Given
/// \code
@@ -4451,7 +4642,7 @@ AST_MATCHER(QualType, isUnsignedInteger) {
return Node->isUnsignedIntegerType();
}
-/// \brief Matches QualType nodes that are of signed integer type.
+/// Matches QualType nodes that are of signed integer type.
///
/// Given
/// \code
@@ -4465,7 +4656,7 @@ AST_MATCHER(QualType, isSignedInteger) {
return Node->isSignedIntegerType();
}
-/// \brief Matches QualType nodes that are of character type.
+/// Matches QualType nodes that are of character type.
///
/// Given
/// \code
@@ -4479,7 +4670,7 @@ AST_MATCHER(QualType, isAnyCharacter) {
return Node->isAnyCharacterType();
}
-/// \brief Matches QualType nodes that are of any pointer type; this includes
+/// Matches QualType nodes that are of any pointer type; this includes
/// the Objective-C object pointer type, which is different despite being
/// syntactically similar.
///
@@ -4499,7 +4690,7 @@ AST_MATCHER(QualType, isAnyPointer) {
return Node->isAnyPointerType();
}
-/// \brief Matches QualType nodes that are const-qualified, i.e., that
+/// Matches QualType nodes that are const-qualified, i.e., that
/// include "top-level" const.
///
/// Given
@@ -4518,7 +4709,7 @@ AST_MATCHER(QualType, isConstQualified) {
return Node.isConstQualified();
}
-/// \brief Matches QualType nodes that are volatile-qualified, i.e., that
+/// Matches QualType nodes that are volatile-qualified, i.e., that
/// include "top-level" volatile.
///
/// Given
@@ -4537,7 +4728,7 @@ AST_MATCHER(QualType, isVolatileQualified) {
return Node.isVolatileQualified();
}
-/// \brief Matches QualType nodes that have local CV-qualifiers attached to
+/// Matches QualType nodes that have local CV-qualifiers attached to
/// the node, not hidden within a typedef.
///
/// Given
@@ -4554,7 +4745,7 @@ AST_MATCHER(QualType, hasLocalQualifiers) {
return Node.hasLocalQualifiers();
}
-/// \brief Matches a member expression where the member is matched by a
+/// Matches a member expression where the member is matched by a
/// given matcher.
///
/// Given
@@ -4571,7 +4762,7 @@ AST_MATCHER_P(MemberExpr, member,
return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
}
-/// \brief Matches a member expression where the object expression is
+/// Matches a member expression where the object expression is
/// matched by a given matcher.
///
/// Given
@@ -4588,7 +4779,7 @@ AST_MATCHER_P(MemberExpr, hasObjectExpression,
return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
}
-/// \brief Matches any using shadow declaration.
+/// Matches any using shadow declaration.
///
/// Given
/// \code
@@ -4603,7 +4794,7 @@ AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl,
Node.shadow_end(), Finder, Builder);
}
-/// \brief Matches a using shadow declaration where the target declaration is
+/// Matches a using shadow declaration where the target declaration is
/// matched by the given matcher.
///
/// Given
@@ -4620,7 +4811,7 @@ AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,
return InnerMatcher.matches(*Node.getTargetDecl(), Finder, Builder);
}
-/// \brief Matches template instantiations of function, class, or static
+/// Matches template instantiations of function, class, or static
/// member variable template instantiations.
///
/// Given
@@ -4631,6 +4822,10 @@ AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,
/// \code
/// template <typename T> class X {}; class A {}; template class X<A>;
/// \endcode
+/// or
+/// \code
+/// template <typename T> class X {}; class A {}; extern template class X<A>;
+/// \endcode
/// cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
/// matches the template instantiation of X<A>.
///
@@ -4648,10 +4843,12 @@ AST_POLYMORPHIC_MATCHER(isTemplateInstantiation,
CXXRecordDecl)) {
return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation ||
Node.getTemplateSpecializationKind() ==
- TSK_ExplicitInstantiationDefinition);
+ TSK_ExplicitInstantiationDefinition ||
+ Node.getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDeclaration);
}
-/// \brief Matches declarations that are template instantiations or are inside
+/// Matches declarations that are template instantiations or are inside
/// template instantiations.
///
/// Given
@@ -4668,7 +4865,7 @@ AST_MATCHER_FUNCTION(internal::Matcher<Decl>, isInstantiated) {
return decl(anyOf(IsInstantiation, hasAncestor(IsInstantiation)));
}
-/// \brief Matches statements inside of a template instantiation.
+/// Matches statements inside of a template instantiation.
///
/// Given
/// \code
@@ -4688,7 +4885,7 @@ AST_MATCHER_FUNCTION(internal::Matcher<Stmt>, isInTemplateInstantiation) {
functionDecl(isTemplateInstantiation())))));
}
-/// \brief Matches explicit template specializations of function, class, or
+/// Matches explicit template specializations of function, class, or
/// static member variable template instantiations.
///
/// Given
@@ -4706,7 +4903,7 @@ AST_POLYMORPHIC_MATCHER(isExplicitTemplateSpecialization,
return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization);
}
-/// \brief Matches \c TypeLocs for which the given inner
+/// Matches \c TypeLocs for which the given inner
/// QualType-matcher matches.
AST_MATCHER_FUNCTION_P_OVERLOAD(internal::BindableMatcher<TypeLoc>, loc,
internal::Matcher<QualType>, InnerMatcher, 0) {
@@ -4714,7 +4911,7 @@ AST_MATCHER_FUNCTION_P_OVERLOAD(internal::BindableMatcher<TypeLoc>, loc,
new internal::TypeLocTypeMatcher(InnerMatcher));
}
-/// \brief Matches type \c bool.
+/// Matches type \c bool.
///
/// Given
/// \code
@@ -4726,7 +4923,7 @@ AST_MATCHER(Type, booleanType) {
return Node.isBooleanType();
}
-/// \brief Matches type \c void.
+/// Matches type \c void.
///
/// Given
/// \code
@@ -4741,7 +4938,7 @@ AST_MATCHER(Type, voidType) {
template <typename NodeType>
using AstTypeMatcher = internal::VariadicDynCastAllOfMatcher<Type, NodeType>;
-/// \brief Matches builtin Types.
+/// Matches builtin Types.
///
/// Given
/// \code
@@ -4755,7 +4952,7 @@ using AstTypeMatcher = internal::VariadicDynCastAllOfMatcher<Type, NodeType>;
/// matches "int b", "float c" and "bool d"
extern const AstTypeMatcher<BuiltinType> builtinType;
-/// \brief Matches all kinds of arrays.
+/// Matches all kinds of arrays.
///
/// Given
/// \code
@@ -4767,7 +4964,7 @@ extern const AstTypeMatcher<BuiltinType> builtinType;
/// matches "int a[]", "int b[4]" and "int c[a[0]]";
extern const AstTypeMatcher<ArrayType> arrayType;
-/// \brief Matches C99 complex types.
+/// Matches C99 complex types.
///
/// Given
/// \code
@@ -4777,7 +4974,7 @@ extern const AstTypeMatcher<ArrayType> arrayType;
/// matches "_Complex float f"
extern const AstTypeMatcher<ComplexType> complexType;
-/// \brief Matches any real floating-point type (float, double, long double).
+/// Matches any real floating-point type (float, double, long double).
///
/// Given
/// \code
@@ -4790,7 +4987,7 @@ AST_MATCHER(Type, realFloatingPointType) {
return Node.isRealFloatingType();
}
-/// \brief Matches arrays and C99 complex types that have a specific element
+/// Matches arrays and C99 complex types that have a specific element
/// type.
///
/// Given
@@ -4807,7 +5004,7 @@ AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasElementType, getElement,
AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
ComplexType));
-/// \brief Matches C arrays with a specified constant size.
+/// Matches C arrays with a specified constant size.
///
/// Given
/// \code
@@ -4821,7 +5018,7 @@ AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasElementType, getElement,
/// matches "int a[2]"
extern const AstTypeMatcher<ConstantArrayType> constantArrayType;
-/// \brief Matches nodes that have the specified size.
+/// Matches nodes that have the specified size.
///
/// Given
/// \code
@@ -4843,7 +5040,7 @@ AST_POLYMORPHIC_MATCHER_P(hasSize,
return internal::HasSizeMatcher<NodeType>::hasSize(Node, N);
}
-/// \brief Matches C++ arrays whose size is a value-dependent expression.
+/// Matches C++ arrays whose size is a value-dependent expression.
///
/// Given
/// \code
@@ -4856,7 +5053,7 @@ AST_POLYMORPHIC_MATCHER_P(hasSize,
/// matches "T data[Size]"
extern const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;
-/// \brief Matches C arrays with unspecified size.
+/// Matches C arrays with unspecified size.
///
/// Given
/// \code
@@ -4868,7 +5065,7 @@ extern const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;
/// matches "int a[]" and "int c[]"
extern const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;
-/// \brief Matches C arrays with a specified size that is not an
+/// Matches C arrays with a specified size that is not an
/// integer-constant-expression.
///
/// Given
@@ -4883,7 +5080,7 @@ extern const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;
/// matches "int c[a[0]]"
extern const AstTypeMatcher<VariableArrayType> variableArrayType;
-/// \brief Matches \c VariableArrayType nodes that have a specific size
+/// Matches \c VariableArrayType nodes that have a specific size
/// expression.
///
/// Given
@@ -4900,7 +5097,7 @@ AST_MATCHER_P(VariableArrayType, hasSizeExpr,
return InnerMatcher.matches(*Node.getSizeExpr(), Finder, Builder);
}
-/// \brief Matches atomic types.
+/// Matches atomic types.
///
/// Given
/// \code
@@ -4910,7 +5107,7 @@ AST_MATCHER_P(VariableArrayType, hasSizeExpr,
/// matches "_Atomic(int) i"
extern const AstTypeMatcher<AtomicType> atomicType;
-/// \brief Matches atomic types with a specific value type.
+/// Matches atomic types with a specific value type.
///
/// Given
/// \code
@@ -4924,7 +5121,7 @@ extern const AstTypeMatcher<AtomicType> atomicType;
AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasValueType, getValue,
AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));
-/// \brief Matches types nodes representing C++11 auto types.
+/// Matches types nodes representing C++11 auto types.
///
/// Given:
/// \code
@@ -4936,7 +5133,19 @@ AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasValueType, getValue,
/// matches "auto n" and "auto i"
extern const AstTypeMatcher<AutoType> autoType;
-/// \brief Matches \c AutoType nodes where the deduced type is a specific type.
+/// Matches types nodes representing C++11 decltype(<expr>) types.
+///
+/// Given:
+/// \code
+/// short i = 1;
+/// int j = 42;
+/// decltype(i + j) result = i + j;
+/// \endcode
+/// decltypeType()
+/// matches "decltype(i + j)"
+extern const AstTypeMatcher<DecltypeType> decltypeType;
+
+/// Matches \c AutoType nodes where the deduced type is a specific type.
///
/// Note: There is no \c TypeLoc for the deduced type and thus no
/// \c getDeducedLoc() matcher.
@@ -4953,7 +5162,21 @@ extern const AstTypeMatcher<AutoType> autoType;
AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType));
-/// \brief Matches \c FunctionType nodes.
+/// Matches \c DecltypeType nodes to find out the underlying type.
+///
+/// Given
+/// \code
+/// decltype(1) a = 1;
+/// decltype(2.0) b = 2.0;
+/// \endcode
+/// decltypeType(hasUnderlyingType(isInteger()))
+/// matches "auto a"
+///
+/// Usable as: Matcher<DecltypeType>
+AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType));
+
+/// Matches \c FunctionType nodes.
///
/// Given
/// \code
@@ -4964,7 +5187,7 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
/// matches "int (*f)(int)" and the type of "g".
extern const AstTypeMatcher<FunctionType> functionType;
-/// \brief Matches \c FunctionProtoType nodes.
+/// Matches \c FunctionProtoType nodes.
///
/// Given
/// \code
@@ -4976,7 +5199,7 @@ extern const AstTypeMatcher<FunctionType> functionType;
/// In C mode, "g" is not matched because it does not contain a prototype.
extern const AstTypeMatcher<FunctionProtoType> functionProtoType;
-/// \brief Matches \c ParenType nodes.
+/// Matches \c ParenType nodes.
///
/// Given
/// \code
@@ -4988,7 +5211,7 @@ extern const AstTypeMatcher<FunctionProtoType> functionProtoType;
/// \c array_of_ptrs.
extern const AstTypeMatcher<ParenType> parenType;
-/// \brief Matches \c ParenType nodes where the inner type is a specific type.
+/// Matches \c ParenType nodes where the inner type is a specific type.
///
/// Given
/// \code
@@ -5003,13 +5226,13 @@ extern const AstTypeMatcher<ParenType> parenType;
AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType,
AST_POLYMORPHIC_SUPPORTED_TYPES(ParenType));
-/// \brief Matches block pointer types, i.e. types syntactically represented as
+/// Matches block pointer types, i.e. types syntactically represented as
/// "void (^)(int)".
///
/// The \c pointee is always required to be a \c FunctionType.
extern const AstTypeMatcher<BlockPointerType> blockPointerType;
-/// \brief Matches member pointer types.
+/// Matches member pointer types.
/// Given
/// \code
/// struct A { int i; }
@@ -5019,7 +5242,7 @@ extern const AstTypeMatcher<BlockPointerType> blockPointerType;
/// matches "A::* ptr"
extern const AstTypeMatcher<MemberPointerType> memberPointerType;
-/// \brief Matches pointer types, but does not match Objective-C object pointer
+/// Matches pointer types, but does not match Objective-C object pointer
/// types.
///
/// Given
@@ -5036,7 +5259,7 @@ extern const AstTypeMatcher<MemberPointerType> memberPointerType;
/// matches "int *a", but does not match "Foo *f".
extern const AstTypeMatcher<PointerType> pointerType;
-/// \brief Matches an Objective-C object pointer type, which is different from
+/// Matches an Objective-C object pointer type, which is different from
/// a pointer type, despite being syntactically similar.
///
/// Given
@@ -5051,7 +5274,7 @@ extern const AstTypeMatcher<PointerType> pointerType;
/// matches "Foo *f", but does not match "int *a".
extern const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType;
-/// \brief Matches both lvalue and rvalue reference types.
+/// Matches both lvalue and rvalue reference types.
///
/// Given
/// \code
@@ -5067,7 +5290,7 @@ extern const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType;
/// \c referenceType() matches the types of \c b, \c c, \c d, \c e, and \c f.
extern const AstTypeMatcher<ReferenceType> referenceType;
-/// \brief Matches lvalue reference types.
+/// Matches lvalue reference types.
///
/// Given:
/// \code
@@ -5084,7 +5307,7 @@ extern const AstTypeMatcher<ReferenceType> referenceType;
/// matched since the type is deduced as int& by reference collapsing rules.
extern const AstTypeMatcher<LValueReferenceType> lValueReferenceType;
-/// \brief Matches rvalue reference types.
+/// Matches rvalue reference types.
///
/// Given:
/// \code
@@ -5101,7 +5324,7 @@ extern const AstTypeMatcher<LValueReferenceType> lValueReferenceType;
/// matched as it is deduced to int& by reference collapsing rules.
extern const AstTypeMatcher<RValueReferenceType> rValueReferenceType;
-/// \brief Narrows PointerType (and similar) matchers to those where the
+/// Narrows PointerType (and similar) matchers to those where the
/// \c pointee matches a given matcher.
///
/// Given
@@ -5120,7 +5343,7 @@ AST_TYPELOC_TRAVERSE_MATCHER_DECL(
AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType,
PointerType, ReferenceType));
-/// \brief Matches typedef types.
+/// Matches typedef types.
///
/// Given
/// \code
@@ -5130,7 +5353,7 @@ AST_TYPELOC_TRAVERSE_MATCHER_DECL(
/// matches "typedef int X"
extern const AstTypeMatcher<TypedefType> typedefType;
-/// \brief Matches enum types.
+/// Matches enum types.
///
/// Given
/// \code
@@ -5145,7 +5368,7 @@ extern const AstTypeMatcher<TypedefType> typedefType;
/// \c s.
extern const AstTypeMatcher<EnumType> enumType;
-/// \brief Matches template specialization types.
+/// Matches template specialization types.
///
/// Given
/// \code
@@ -5161,7 +5384,7 @@ extern const AstTypeMatcher<EnumType> enumType;
extern const AstTypeMatcher<TemplateSpecializationType>
templateSpecializationType;
-/// \brief Matches types nodes representing unary type transformations.
+/// Matches types nodes representing unary type transformations.
///
/// Given:
/// \code
@@ -5171,7 +5394,7 @@ extern const AstTypeMatcher<TemplateSpecializationType>
/// matches "__underlying_type(T)"
extern const AstTypeMatcher<UnaryTransformType> unaryTransformType;
-/// \brief Matches record types (e.g. structs, classes).
+/// Matches record types (e.g. structs, classes).
///
/// Given
/// \code
@@ -5186,7 +5409,7 @@ extern const AstTypeMatcher<UnaryTransformType> unaryTransformType;
/// and \c s.
extern const AstTypeMatcher<RecordType> recordType;
-/// \brief Matches tag types (record and enum types).
+/// Matches tag types (record and enum types).
///
/// Given
/// \code
@@ -5201,7 +5424,7 @@ extern const AstTypeMatcher<RecordType> recordType;
/// and \c c.
extern const AstTypeMatcher<TagType> tagType;
-/// \brief Matches types specified with an elaborated type keyword or with a
+/// Matches types specified with an elaborated type keyword or with a
/// qualified name.
///
/// Given
@@ -5221,7 +5444,7 @@ extern const AstTypeMatcher<TagType> tagType;
/// \c c and \c d.
extern const AstTypeMatcher<ElaboratedType> elaboratedType;
-/// \brief Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
+/// Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
/// matches \c InnerMatcher if the qualifier exists.
///
/// Given
@@ -5244,7 +5467,7 @@ AST_MATCHER_P(ElaboratedType, hasQualifier,
return false;
}
-/// \brief Matches ElaboratedTypes whose named type matches \c InnerMatcher.
+/// Matches ElaboratedTypes whose named type matches \c InnerMatcher.
///
/// Given
/// \code
@@ -5264,7 +5487,7 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);
}
-/// \brief Matches types that represent the result of substituting a type for a
+/// Matches types that represent the result of substituting a type for a
/// template type parameter.
///
/// Given
@@ -5279,7 +5502,7 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
extern const AstTypeMatcher<SubstTemplateTypeParmType>
substTemplateTypeParmType;
-/// \brief Matches template type parameter substitutions that have a replacement
+/// Matches template type parameter substitutions that have a replacement
/// type that matches the provided matcher.
///
/// Given
@@ -5295,7 +5518,7 @@ AST_TYPE_TRAVERSE_MATCHER(
hasReplacementType, getReplacementType,
AST_POLYMORPHIC_SUPPORTED_TYPES(SubstTemplateTypeParmType));
-/// \brief Matches template type parameter types.
+/// Matches template type parameter types.
///
/// Example matches T, but not int.
/// (matcher = templateTypeParmType())
@@ -5304,7 +5527,7 @@ AST_TYPE_TRAVERSE_MATCHER(
/// \endcode
extern const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
-/// \brief Matches injected class name types.
+/// Matches injected class name types.
///
/// Example matches S s, but not S<T> s.
/// (matcher = parmVarDecl(hasType(injectedClassNameType())))
@@ -5316,7 +5539,7 @@ extern const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
/// \endcode
extern const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;
-/// \brief Matches decayed type
+/// Matches decayed type
/// Example matches i[] in declaration of f.
/// (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType())))))
/// Example matches i[1].
@@ -5328,13 +5551,13 @@ extern const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;
/// \endcode
extern const AstTypeMatcher<DecayedType> decayedType;
-/// \brief Matches the decayed type, whos decayed type matches \c InnerMatcher
+/// Matches the decayed type, whos decayed type matches \c InnerMatcher
AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher<QualType>,
InnerType) {
return InnerType.matches(Node.getDecayedType(), Finder, Builder);
}
-/// \brief Matches declarations whose declaration context, interpreted as a
+/// Matches declarations whose declaration context, interpreted as a
/// Decl, matches \c InnerMatcher.
///
/// Given
@@ -5354,7 +5577,7 @@ AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher) {
return InnerMatcher.matches(*Decl::castFromDeclContext(DC), Finder, Builder);
}
-/// \brief Matches nested name specifiers.
+/// Matches nested name specifiers.
///
/// Given
/// \code
@@ -5370,11 +5593,11 @@ AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher) {
extern const internal::VariadicAllOfMatcher<NestedNameSpecifier>
nestedNameSpecifier;
-/// \brief Same as \c nestedNameSpecifier but matches \c NestedNameSpecifierLoc.
+/// Same as \c nestedNameSpecifier but matches \c NestedNameSpecifierLoc.
extern const internal::VariadicAllOfMatcher<NestedNameSpecifierLoc>
nestedNameSpecifierLoc;
-/// \brief Matches \c NestedNameSpecifierLocs for which the given inner
+/// Matches \c NestedNameSpecifierLocs for which the given inner
/// NestedNameSpecifier-matcher matches.
AST_MATCHER_FUNCTION_P_OVERLOAD(
internal::BindableMatcher<NestedNameSpecifierLoc>, loc,
@@ -5384,7 +5607,7 @@ AST_MATCHER_FUNCTION_P_OVERLOAD(
InnerMatcher));
}
-/// \brief Matches nested name specifiers that specify a type matching the
+/// Matches nested name specifiers that specify a type matching the
/// given \c QualType matcher without qualifiers.
///
/// Given
@@ -5403,7 +5626,7 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesType,
return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder);
}
-/// \brief Matches nested name specifier locs that specify a type matching the
+/// Matches nested name specifier locs that specify a type matching the
/// given \c TypeLoc.
///
/// Given
@@ -5416,10 +5639,11 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesType,
/// matches "A::"
AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
internal::Matcher<TypeLoc>, InnerMatcher) {
- return Node && InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
+ return Node && Node.getNestedNameSpecifier()->getAsType() &&
+ InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
}
-/// \brief Matches on the prefix of a \c NestedNameSpecifier.
+/// Matches on the prefix of a \c NestedNameSpecifier.
///
/// Given
/// \code
@@ -5437,7 +5661,7 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
return InnerMatcher.matches(*NextNode, Finder, Builder);
}
-/// \brief Matches on the prefix of a \c NestedNameSpecifierLoc.
+/// Matches on the prefix of a \c NestedNameSpecifierLoc.
///
/// Given
/// \code
@@ -5455,7 +5679,7 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
return InnerMatcher.matches(NextNode, Finder, Builder);
}
-/// \brief Matches nested name specifiers that specify a namespace matching the
+/// Matches nested name specifiers that specify a namespace matching the
/// given namespace matcher.
///
/// Given
@@ -5472,23 +5696,23 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
}
-/// \brief Overloads for the \c equalsNode matcher.
+/// Overloads for the \c equalsNode matcher.
/// FIXME: Implement for other node types.
/// @{
-/// \brief Matches if a node equals another node.
+/// Matches if a node equals another node.
///
/// \c Decl has pointer identity in the AST.
AST_MATCHER_P_OVERLOAD(Decl, equalsNode, const Decl*, Other, 0) {
return &Node == Other;
}
-/// \brief Matches if a node equals another node.
+/// Matches if a node equals another node.
///
/// \c Stmt has pointer identity in the AST.
AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) {
return &Node == Other;
}
-/// \brief Matches if a node equals another node.
+/// Matches if a node equals another node.
///
/// \c Type has pointer identity in the AST.
AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) {
@@ -5497,7 +5721,7 @@ AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) {
/// @}
-/// \brief Matches each case or default statement belonging to the given switch
+/// Matches each case or default statement belonging to the given switch
/// statement. This matcher may produce multiple matches.
///
/// Given
@@ -5529,7 +5753,7 @@ AST_MATCHER_P(SwitchStmt, forEachSwitchCase, internal::Matcher<SwitchCase>,
return Matched;
}
-/// \brief Matches each constructor initializer in a constructor definition.
+/// Matches each constructor initializer in a constructor definition.
///
/// Given
/// \code
@@ -5554,7 +5778,7 @@ AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer,
return Matched;
}
-/// \brief Matches constructor declarations that are copy constructors.
+/// Matches constructor declarations that are copy constructors.
///
/// Given
/// \code
@@ -5569,7 +5793,7 @@ AST_MATCHER(CXXConstructorDecl, isCopyConstructor) {
return Node.isCopyConstructor();
}
-/// \brief Matches constructor declarations that are move constructors.
+/// Matches constructor declarations that are move constructors.
///
/// Given
/// \code
@@ -5584,7 +5808,7 @@ AST_MATCHER(CXXConstructorDecl, isMoveConstructor) {
return Node.isMoveConstructor();
}
-/// \brief Matches constructor declarations that are default constructors.
+/// Matches constructor declarations that are default constructors.
///
/// Given
/// \code
@@ -5599,7 +5823,7 @@ AST_MATCHER(CXXConstructorDecl, isDefaultConstructor) {
return Node.isDefaultConstructor();
}
-/// \brief Matches constructors that delegate to another constructor.
+/// Matches constructors that delegate to another constructor.
///
/// Given
/// \code
@@ -5616,7 +5840,7 @@ AST_MATCHER(CXXConstructorDecl, isDelegatingConstructor) {
return Node.isDelegatingConstructor();
}
-/// \brief Matches constructor and conversion declarations that are marked with
+/// Matches constructor and conversion declarations that are marked with
/// the explicit keyword.
///
/// Given
@@ -5636,7 +5860,7 @@ AST_POLYMORPHIC_MATCHER(isExplicit,
return Node.isExplicit();
}
-/// \brief Matches function and namespace declarations that are marked with
+/// Matches function and namespace declarations that are marked with
/// the inline keyword.
///
/// Given
@@ -5661,7 +5885,7 @@ AST_POLYMORPHIC_MATCHER(isInline,
llvm_unreachable("Not a valid polymorphic type");
}
-/// \brief Matches anonymous namespace declarations.
+/// Matches anonymous namespace declarations.
///
/// Given
/// \code
@@ -5674,7 +5898,7 @@ AST_MATCHER(NamespaceDecl, isAnonymous) {
return Node.isAnonymousNamespace();
}
-/// \brief If the given case statement does not use the GNU case range
+/// If the given case statement does not use the GNU case range
/// extension, matches the constant given in the statement.
///
/// Given
@@ -5691,7 +5915,7 @@ AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher<Expr>,
return InnerMatcher.matches(*Node.getLHS(), Finder, Builder);
}
-/// \brief Matches declaration that has a given attribute.
+/// Matches declaration that has a given attribute.
///
/// Given
/// \code
@@ -5708,7 +5932,7 @@ AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) {
return false;
}
-/// \brief Matches the return value expression of a return statement
+/// Matches the return value expression of a return statement
///
/// Given
/// \code
@@ -5725,7 +5949,7 @@ AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher<Expr>,
return false;
}
-/// \brief Matches CUDA kernel call expression.
+/// Matches CUDA kernel call expression.
///
/// Example matches,
/// \code
@@ -5734,7 +5958,7 @@ AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher<Expr>,
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
cudaKernelCallExpr;
-/// \brief Matches expressions that resolve to a null pointer constant, such as
+/// Matches expressions that resolve to a null pointer constant, such as
/// GNU's __null, C++11's nullptr, or C's NULL macro.
///
/// Given:
@@ -5755,7 +5979,7 @@ AST_MATCHER_FUNCTION(internal::Matcher<Expr>, nullPointerConstant) {
integerLiteral(equals(0), hasParent(expr(hasType(pointerType())))));
}
-/// \brief Matches declaration of the function the statement belongs to
+/// Matches declaration of the function the statement belongs to
///
/// Given:
/// \code
@@ -5793,7 +6017,7 @@ AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>,
return false;
}
-/// \brief Matches a declaration that has external formal linkage.
+/// Matches a declaration that has external formal linkage.
///
/// Example matches only z (matcher = varDecl(hasExternalFormalLinkage()))
/// \code
@@ -5817,7 +6041,7 @@ AST_MATCHER(NamedDecl, hasExternalFormalLinkage) {
return Node.hasExternalFormalLinkage();
}
-/// \brief Matches a declaration that has default arguments.
+/// Matches a declaration that has default arguments.
///
/// Example matches y (matcher = parmVarDecl(hasDefaultArgument()))
/// \code
@@ -5828,7 +6052,7 @@ AST_MATCHER(ParmVarDecl, hasDefaultArgument) {
return Node.hasDefaultArg();
}
-/// \brief Matches array new expressions.
+/// Matches array new expressions.
///
/// Given:
/// \code
@@ -5840,7 +6064,7 @@ AST_MATCHER(CXXNewExpr, isArray) {
return Node.isArray();
}
-/// \brief Matches array new expressions with a given array size.
+/// Matches array new expressions with a given array size.
///
/// Given:
/// \code
@@ -5853,7 +6077,7 @@ AST_MATCHER_P(CXXNewExpr, hasArraySize, internal::Matcher<Expr>, InnerMatcher) {
InnerMatcher.matches(*Node.getArraySize(), Finder, Builder);
}
-/// \brief Matches a class declaration that is defined.
+/// Matches a class declaration that is defined.
///
/// Example matches x (matcher = cxxRecordDecl(hasDefinition()))
/// \code
@@ -5864,6 +6088,30 @@ AST_MATCHER(CXXRecordDecl, hasDefinition) {
return Node.hasDefinition();
}
+/// Matches C++11 scoped enum declaration.
+///
+/// Example matches Y (matcher = enumDecl(isScoped()))
+/// \code
+/// enum X {};
+/// enum class Y {};
+/// \endcode
+AST_MATCHER(EnumDecl, isScoped) {
+ return Node.isScoped();
+}
+
+/// Matches a function declared with a trailing return type.
+///
+/// Example matches Y (matcher = functionDecl(hasTrailingReturn()))
+/// \code
+/// int X() {}
+/// auto Y() -> int {}
+/// \endcode
+AST_MATCHER(FunctionDecl, hasTrailingReturn) {
+ if (const auto *F = Node.getType()->getAs<FunctionProtoType>())
+ return F->hasTrailingReturn();
+ return false;
+}
+
} // namespace ast_matchers
} // namespace clang
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 8bd61a76e1852..9d9f867d053ad 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -38,9 +38,12 @@
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/TemplateName.h"
@@ -80,7 +83,7 @@ class BoundNodes;
namespace internal {
-/// \brief Variadic function object.
+/// Variadic function object.
///
/// Most of the functions below that use VariadicFunction could be implemented
/// using plain C++11 variadic functions, but the function object allows us to
@@ -113,19 +116,23 @@ private:
}
};
-/// \brief Unifies obtaining the underlying type of a regular node through
+/// Unifies obtaining the underlying type of a regular node through
/// `getType` and a TypedefNameDecl node through `getUnderlyingType`.
inline QualType getUnderlyingType(const Expr &Node) { return Node.getType(); }
inline QualType getUnderlyingType(const ValueDecl &Node) {
return Node.getType();
}
-
inline QualType getUnderlyingType(const TypedefNameDecl &Node) {
return Node.getUnderlyingType();
}
+inline QualType getUnderlyingType(const FriendDecl &Node) {
+ if (const TypeSourceInfo *TSI = Node.getFriendType())
+ return TSI->getType();
+ return QualType();
+}
-/// \brief Unifies obtaining the FunctionProtoType pointer from both
+/// Unifies obtaining the FunctionProtoType pointer from both
/// FunctionProtoType and FunctionDecl nodes..
inline const FunctionProtoType *
getFunctionProtoType(const FunctionProtoType &Node) {
@@ -136,17 +143,17 @@ inline const FunctionProtoType *getFunctionProtoType(const FunctionDecl &Node) {
return Node.getType()->getAs<FunctionProtoType>();
}
-/// \brief Internal version of BoundNodes. Holds all the bound nodes.
+/// Internal version of BoundNodes. Holds all the bound nodes.
class BoundNodesMap {
public:
- /// \brief Adds \c Node to the map with key \c ID.
+ /// Adds \c Node to the map with key \c ID.
///
/// The node's base type should be in NodeBaseType or it will be unaccessible.
void addNode(StringRef ID, const ast_type_traits::DynTypedNode& DynNode) {
NodeMap[ID] = DynNode;
}
- /// \brief Returns the AST node bound to \c ID.
+ /// Returns the AST node bound to \c ID.
///
/// Returns NULL if there was no node bound to \c ID or if there is a node but
/// it cannot be converted to the specified type.
@@ -167,12 +174,12 @@ public:
return It->second;
}
- /// \brief Imposes an order on BoundNodesMaps.
+ /// Imposes an order on BoundNodesMaps.
bool operator<(const BoundNodesMap &Other) const {
return NodeMap < Other.NodeMap;
}
- /// \brief A map from IDs to the bound nodes.
+ /// A map from IDs to the bound nodes.
///
/// Note that we're using std::map here, as for memoization:
/// - we need a comparison operator
@@ -183,7 +190,7 @@ public:
return NodeMap;
}
- /// \brief Returns \c true if this \c BoundNodesMap can be compared, i.e. all
+ /// Returns \c true if this \c BoundNodesMap can be compared, i.e. all
/// stored nodes have memoization data.
bool isComparable() const {
for (const auto &IDAndNode : NodeMap) {
@@ -197,25 +204,25 @@ private:
IDToNodeMap NodeMap;
};
-/// \brief Creates BoundNodesTree objects.
+/// Creates BoundNodesTree objects.
///
/// The tree builder is used during the matching process to insert the bound
/// nodes from the Id matcher.
class BoundNodesTreeBuilder {
public:
- /// \brief A visitor interface to visit all BoundNodes results for a
+ /// A visitor interface to visit all BoundNodes results for a
/// BoundNodesTree.
class Visitor {
public:
virtual ~Visitor() = default;
- /// \brief Called multiple times during a single call to VisitMatches(...).
+ /// Called multiple times during a single call to VisitMatches(...).
///
/// 'BoundNodesView' contains the bound nodes for a single match.
virtual void visitMatch(const BoundNodes& BoundNodesView) = 0;
};
- /// \brief Add a binding from an id to a node.
+ /// Add a binding from an id to a node.
void setBinding(StringRef Id, const ast_type_traits::DynTypedNode &DynNode) {
if (Bindings.empty())
Bindings.emplace_back();
@@ -223,10 +230,10 @@ public:
Binding.addNode(Id, DynNode);
}
- /// \brief Adds a branch in the tree.
+ /// Adds a branch in the tree.
void addMatch(const BoundNodesTreeBuilder &Bindings);
- /// \brief Visits all matches that this BoundNodesTree represents.
+ /// Visits all matches that this BoundNodesTree represents.
///
/// The ownership of 'ResultVisitor' remains at the caller.
void visitMatches(Visitor* ResultVisitor);
@@ -238,12 +245,12 @@ public:
return !Bindings.empty();
}
- /// \brief Imposes an order on BoundNodesTreeBuilders.
+ /// Imposes an order on BoundNodesTreeBuilders.
bool operator<(const BoundNodesTreeBuilder &Other) const {
return Bindings < Other.Bindings;
}
- /// \brief Returns \c true if this \c BoundNodesTreeBuilder can be compared,
+ /// Returns \c true if this \c BoundNodesTreeBuilder can be compared,
/// i.e. all stored node maps have memoization data.
bool isComparable() const {
for (const BoundNodesMap &NodesMap : Bindings) {
@@ -259,7 +266,7 @@ private:
class ASTMatchFinder;
-/// \brief Generic interface for all matchers.
+/// Generic interface for all matchers.
///
/// Used by the implementation of Matcher<T> and DynTypedMatcher.
/// In general, implement MatcherInterface<T> or SingleNodeMatcherInterface<T>
@@ -269,7 +276,7 @@ class DynMatcherInterface
public:
virtual ~DynMatcherInterface() = default;
- /// \brief Returns true if \p DynNode can be matched.
+ /// Returns true if \p DynNode can be matched.
///
/// May bind \p DynNode to an ID via \p Builder, or recurse into
/// the AST via \p Finder.
@@ -278,7 +285,7 @@ public:
BoundNodesTreeBuilder *Builder) const = 0;
};
-/// \brief Generic interface for matchers on an AST node of type T.
+/// Generic interface for matchers on an AST node of type T.
///
/// Implement this if your matcher may need to inspect the children or
/// descendants of the node or bind matched nodes to names. If you are
@@ -288,7 +295,7 @@ public:
template <typename T>
class MatcherInterface : public DynMatcherInterface {
public:
- /// \brief Returns true if 'Node' can be matched.
+ /// Returns true if 'Node' can be matched.
///
/// May bind 'Node' to an ID via 'Builder', or recurse into
/// the AST via 'Finder'.
@@ -303,12 +310,12 @@ public:
}
};
-/// \brief Interface for matchers that only evaluate properties on a single
+/// Interface for matchers that only evaluate properties on a single
/// node.
template <typename T>
class SingleNodeMatcherInterface : public MatcherInterface<T> {
public:
- /// \brief Returns true if the matcher matches the provided node.
+ /// Returns true if the matcher matches the provided node.
///
/// A subclass must implement this instead of Matches().
virtual bool matchesNode(const T &Node) const = 0;
@@ -324,7 +331,7 @@ private:
template <typename> class Matcher;
-/// \brief Matcher that works on a \c DynTypedNode.
+/// Matcher that works on a \c DynTypedNode.
///
/// It is constructed from a \c Matcher<T> object and redirects most calls to
/// underlying matcher.
@@ -333,26 +340,26 @@ template <typename> class Matcher;
/// return false if it is not convertible.
class DynTypedMatcher {
public:
- /// \brief Takes ownership of the provided implementation pointer.
+ /// Takes ownership of the provided implementation pointer.
template <typename T>
DynTypedMatcher(MatcherInterface<T> *Implementation)
: SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
RestrictKind(SupportedKind), Implementation(Implementation) {}
- /// \brief Construct from a variadic function.
+ /// Construct from a variadic function.
enum VariadicOperator {
- /// \brief Matches nodes for which all provided matchers match.
+ /// Matches nodes for which all provided matchers match.
VO_AllOf,
- /// \brief Matches nodes for which at least one of the provided matchers
+ /// Matches nodes for which at least one of the provided matchers
/// matches.
VO_AnyOf,
- /// \brief Matches nodes for which at least one of the provided matchers
+ /// Matches nodes for which at least one of the provided matchers
/// matches, but doesn't stop at the first match.
VO_EachOf,
- /// \brief Matches nodes that do not match the provided matcher.
+ /// Matches nodes that do not match the provided matcher.
///
/// Uses the variadic matcher interface, but fails if
/// InnerMatchers.size() != 1.
@@ -364,27 +371,27 @@ public:
ast_type_traits::ASTNodeKind SupportedKind,
std::vector<DynTypedMatcher> InnerMatchers);
- /// \brief Get a "true" matcher for \p NodeKind.
+ /// Get a "true" matcher for \p NodeKind.
///
/// It only checks that the node is of the right kind.
static DynTypedMatcher trueMatcher(ast_type_traits::ASTNodeKind NodeKind);
void setAllowBind(bool AB) { AllowBind = AB; }
- /// \brief Check whether this matcher could ever match a node of kind \p Kind.
+ /// Check whether this matcher could ever match a node of kind \p Kind.
/// \return \c false if this matcher will never match such a node. Otherwise,
/// return \c true.
bool canMatchNodesOfKind(ast_type_traits::ASTNodeKind Kind) const;
- /// \brief Return a matcher that points to the same implementation, but
+ /// Return a matcher that points to the same implementation, but
/// restricts the node types for \p Kind.
DynTypedMatcher dynCastTo(const ast_type_traits::ASTNodeKind Kind) const;
- /// \brief Returns true if the matcher matches the given \c DynNode.
+ /// Returns true if the matcher matches the given \c DynNode.
bool matches(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const;
- /// \brief Same as matches(), but skips the kind check.
+ /// Same as matches(), but skips the kind check.
///
/// It is faster, but the caller must ensure the node is valid for the
/// kind of this matcher.
@@ -392,12 +399,12 @@ public:
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const;
- /// \brief Bind the specified \p ID to the matcher.
+ /// Bind the specified \p ID to the matcher.
/// \return A new matcher with the \p ID bound to it if this matcher supports
/// binding. Otherwise, returns an empty \c Optional<>.
llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const;
- /// \brief Returns a unique \p ID for the matcher.
+ /// Returns a unique \p ID for the matcher.
///
/// Casting a Matcher<T> to Matcher<U> creates a matcher that has the
/// same \c Implementation pointer, but different \c RestrictKind. We need to
@@ -412,7 +419,7 @@ public:
reinterpret_cast<uint64_t>(Implementation.get()));
}
- /// \brief Returns the type this matcher works on.
+ /// Returns the type this matcher works on.
///
/// \c matches() will always return false unless the node passed is of this
/// or a derived type.
@@ -420,7 +427,7 @@ public:
return SupportedKind;
}
- /// \brief Returns \c true if the passed \c DynTypedMatcher can be converted
+ /// Returns \c true if the passed \c DynTypedMatcher can be converted
/// to a \c Matcher<T>.
///
/// This method verifies that the underlying matcher in \c Other can process
@@ -430,7 +437,7 @@ public:
}
bool canConvertTo(ast_type_traits::ASTNodeKind To) const;
- /// \brief Construct a \c Matcher<T> interface around the dynamic matcher.
+ /// Construct a \c Matcher<T> interface around the dynamic matcher.
///
/// This method asserts that \c canConvertTo() is \c true. Callers
/// should call \c canConvertTo() first to make sure that \c this is
@@ -440,7 +447,7 @@ public:
return unconditionalConvertTo<T>();
}
- /// \brief Same as \c convertTo(), but does not check that the underlying
+ /// Same as \c convertTo(), but does not check that the underlying
/// matcher can handle a value of T.
///
/// If it is not compatible, then this matcher will never match anything.
@@ -456,7 +463,7 @@ private:
bool AllowBind = false;
ast_type_traits::ASTNodeKind SupportedKind;
- /// \brief A potentially stricter node kind.
+ /// A potentially stricter node kind.
///
/// It allows to perform implicit and dynamic cast of matchers without
/// needing to change \c Implementation.
@@ -464,7 +471,7 @@ private:
IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
};
-/// \brief Wrapper base class for a wrapping matcher.
+/// Wrapper base class for a wrapping matcher.
///
/// This is just a container for a DynTypedMatcher that can be used as a base
/// class for another matcher.
@@ -477,7 +484,7 @@ protected:
const DynTypedMatcher InnerMatcher;
};
-/// \brief Wrapper of a MatcherInterface<T> *that allows copying.
+/// Wrapper of a MatcherInterface<T> *that allows copying.
///
/// A Matcher<Base> can be used anywhere a Matcher<Derived> is
/// required. This establishes an is-a relationship which is reverse
@@ -488,11 +495,11 @@ protected:
template <typename T>
class Matcher {
public:
- /// \brief Takes ownership of the provided implementation pointer.
+ /// Takes ownership of the provided implementation pointer.
explicit Matcher(MatcherInterface<T> *Implementation)
: Implementation(Implementation) {}
- /// \brief Implicitly converts \c Other to a Matcher<T>.
+ /// Implicitly converts \c Other to a Matcher<T>.
///
/// Requires \c T to be derived from \c From.
template <typename From>
@@ -504,7 +511,7 @@ public:
ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
}
- /// \brief Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
+ /// Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
///
/// The resulting matcher is not strict, i.e. ignores qualifiers.
template <typename TypeT>
@@ -514,7 +521,7 @@ public:
std::is_same<TypeT, Type>::value>::type* = nullptr)
: Implementation(new TypeToQualType<TypeT>(Other)) {}
- /// \brief Convert \c this into a \c Matcher<T> by applying dyn_cast<> to the
+ /// Convert \c this into a \c Matcher<T> by applying dyn_cast<> to the
/// argument.
/// \c To must be a base class of \c T.
template <typename To>
@@ -523,7 +530,7 @@ public:
return Matcher<To>(Implementation);
}
- /// \brief Forwards the call to the underlying MatcherInterface<T> pointer.
+ /// Forwards the call to the underlying MatcherInterface<T> pointer.
bool matches(const T &Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
@@ -531,18 +538,18 @@ public:
Finder, Builder);
}
- /// \brief Returns an ID that uniquely identifies the matcher.
+ /// Returns an ID that uniquely identifies the matcher.
DynTypedMatcher::MatcherIDType getID() const {
return Implementation.getID();
}
- /// \brief Extract the dynamic matcher.
+ /// Extract the dynamic matcher.
///
/// The returned matcher keeps the same restrictions as \c this and remembers
/// that it is meant to support nodes of type \c T.
operator DynTypedMatcher() const { return Implementation; }
- /// \brief Allows the conversion of a \c Matcher<Type> to a \c
+ /// Allows the conversion of a \c Matcher<Type> to a \c
/// Matcher<QualType>.
///
/// Depending on the constructor argument, the matcher is either strict, i.e.
@@ -583,14 +590,14 @@ private:
DynTypedMatcher Implementation;
}; // class Matcher
-/// \brief A convenient helper for creating a Matcher<T> without specifying
+/// A convenient helper for creating a Matcher<T> without specifying
/// the template type argument.
template <typename T>
inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
return Matcher<T>(Implementation);
}
-/// \brief Specialization of the conversion functions for QualType.
+/// Specialization of the conversion functions for QualType.
///
/// This specialization provides the Matcher<Type>->Matcher<QualType>
/// conversion that the static API does.
@@ -606,7 +613,7 @@ inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {
return unconditionalConvertTo<QualType>();
}
-/// \brief Finds the first node in a range that matches the given matcher.
+/// Finds the first node in a range that matches the given matcher.
template <typename MatcherT, typename IteratorT>
bool matchesFirstInRange(const MatcherT &Matcher, IteratorT Start,
IteratorT End, ASTMatchFinder *Finder,
@@ -621,7 +628,7 @@ bool matchesFirstInRange(const MatcherT &Matcher, IteratorT Start,
return false;
}
-/// \brief Finds the first node in a pointer range that matches the given
+/// Finds the first node in a pointer range that matches the given
/// matcher.
template <typename MatcherT, typename IteratorT>
bool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start,
@@ -653,7 +660,7 @@ public:
static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes);
};
-/// \brief Matches overloaded operators with a specific name.
+/// Matches overloaded operators with a specific name.
///
/// The type argument ArgT is not used by this matcher but is used by
/// PolymorphicMatcherWithParam1 and should be StringRef.
@@ -675,14 +682,14 @@ public:
private:
- /// \brief CXXOperatorCallExpr exist only for calls to overloaded operators
+ /// CXXOperatorCallExpr exist only for calls to overloaded operators
/// so this function returns true if the call is to an operator of the given
/// name.
bool matchesSpecialized(const CXXOperatorCallExpr &Node) const {
return getOperatorSpelling(Node.getOperator()) == Name;
}
- /// \brief Returns true only if CXXMethodDecl represents an overloaded
+ /// Returns true only if CXXMethodDecl represents an overloaded
/// operator and has the given operator name.
bool matchesSpecialized(const FunctionDecl &Node) const {
return Node.isOverloadedOperator() &&
@@ -692,7 +699,7 @@ private:
std::string Name;
};
-/// \brief Matches named declarations with a specific name.
+/// Matches named declarations with a specific name.
///
/// See \c hasName() and \c hasAnyName() in ASTMatchers.h for details.
class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
@@ -702,13 +709,13 @@ class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
bool matchesNode(const NamedDecl &Node) const override;
private:
- /// \brief Unqualified match routine.
+ /// Unqualified match routine.
///
/// It is much faster than the full match, but it only works for unqualified
/// matches.
bool matchesNodeUnqualified(const NamedDecl &Node) const;
- /// \brief Full match routine
+ /// Full match routine
///
/// Fast implementation for the simple case of a named declaration at
/// namespace or RecordDecl scope.
@@ -716,7 +723,7 @@ class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
/// matchesNodeFullSlow.
bool matchesNodeFullFast(const NamedDecl &Node) const;
- /// \brief Full match routine
+ /// Full match routine
///
/// It generates the fully qualified name of the declaration (which is
/// expensive) before trying to match.
@@ -727,11 +734,16 @@ class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
const std::vector<std::string> Names;
};
-/// \brief Trampoline function to use VariadicFunction<> to construct a
+/// Trampoline function to use VariadicFunction<> to construct a
/// HasNameMatcher.
Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs);
-/// \brief Matches declarations for QualType and CallExpr.
+/// Trampoline function to use VariadicFunction<> to construct a
+/// hasAnySelector matcher.
+Matcher<ObjCMessageExpr> hasAnySelectorFunc(
+ ArrayRef<const StringRef *> NameRefs);
+
+/// Matches declarations for QualType and CallExpr.
///
/// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but
/// not actually used.
@@ -750,7 +762,7 @@ public:
}
private:
- /// \brief Forwards to matching on the underlying type of the QualType.
+ /// Forwards to matching on the underlying type of the QualType.
bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
if (Node.isNull())
@@ -759,7 +771,7 @@ private:
return matchesSpecialized(*Node, Finder, Builder);
}
- /// \brief Finds the best declaration for a type and returns whether the inner
+ /// Finds the best declaration for a type and returns whether the inner
/// matcher matches on it.
bool matchesSpecialized(const Type &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
@@ -833,21 +845,21 @@ private:
return false;
}
- /// \brief Extracts the Decl the DeclRefExpr references and returns whether
+ /// Extracts the Decl the DeclRefExpr references and returns whether
/// the inner matcher matches on it.
bool matchesSpecialized(const DeclRefExpr &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
return matchesDecl(Node.getDecl(), Finder, Builder);
}
- /// \brief Extracts the Decl of the callee of a CallExpr and returns whether
+ /// Extracts the Decl of the callee of a CallExpr and returns whether
/// the inner matcher matches on it.
bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
return matchesDecl(Node.getCalleeDecl(), Finder, Builder);
}
- /// \brief Extracts the Decl of the constructor call and returns whether the
+ /// Extracts the Decl of the constructor call and returns whether the
/// inner matcher matches on it.
bool matchesSpecialized(const CXXConstructExpr &Node,
ASTMatchFinder *Finder,
@@ -855,7 +867,13 @@ private:
return matchesDecl(Node.getConstructor(), Finder, Builder);
}
- /// \brief Extracts the operator new of the new call and returns whether the
+ bool matchesSpecialized(const ObjCIvarRefExpr &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ return matchesDecl(Node.getDecl(), Finder, Builder);
+ }
+
+ /// Extracts the operator new of the new call and returns whether the
/// inner matcher matches on it.
bool matchesSpecialized(const CXXNewExpr &Node,
ASTMatchFinder *Finder,
@@ -863,7 +881,7 @@ private:
return matchesDecl(Node.getOperatorNew(), Finder, Builder);
}
- /// \brief Extracts the \c ValueDecl a \c MemberExpr refers to and returns
+ /// Extracts the \c ValueDecl a \c MemberExpr refers to and returns
/// whether the inner matcher matches on it.
bool matchesSpecialized(const MemberExpr &Node,
ASTMatchFinder *Finder,
@@ -871,7 +889,7 @@ private:
return matchesDecl(Node.getMemberDecl(), Finder, Builder);
}
- /// \brief Extracts the \c LabelDecl a \c AddrLabelExpr refers to and returns
+ /// Extracts the \c LabelDecl a \c AddrLabelExpr refers to and returns
/// whether the inner matcher matches on it.
bool matchesSpecialized(const AddrLabelExpr &Node,
ASTMatchFinder *Finder,
@@ -879,14 +897,14 @@ private:
return matchesDecl(Node.getLabel(), Finder, Builder);
}
- /// \brief Extracts the declaration of a LabelStmt and returns whether the
+ /// Extracts the declaration of a LabelStmt and returns whether the
/// inner matcher matches on it.
bool matchesSpecialized(const LabelStmt &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
return matchesDecl(Node.getDecl(), Finder, Builder);
}
- /// \brief Returns whether the inner matcher \c Node. Returns false if \c Node
+ /// Returns whether the inner matcher \c Node. Returns false if \c Node
/// is \c NULL.
bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
@@ -896,7 +914,7 @@ private:
}
};
-/// \brief IsBaseType<T>::value is true if T is a "base" type in the AST
+/// IsBaseType<T>::value is true if T is a "base" type in the AST
/// node class hierarchies.
template <typename T>
struct IsBaseType {
@@ -913,7 +931,7 @@ struct IsBaseType {
template <typename T>
const bool IsBaseType<T>::value;
-/// \brief Interface that allows matchers to traverse the AST.
+/// Interface that allows matchers to traverse the AST.
/// FIXME: Find a better name.
///
/// This provides three entry methods for each base node type in the AST:
@@ -933,7 +951,7 @@ const bool IsBaseType<T>::value;
/// all nodes, as all nodes have ancestors.
class ASTMatchFinder {
public:
- /// \brief Defines how we descend a level in the AST when we pass
+ /// Defines how we descend a level in the AST when we pass
/// through expressions.
enum TraversalKind {
/// Will traverse any child nodes.
@@ -943,7 +961,7 @@ public:
TK_IgnoreImplicitCastsAndParentheses
};
- /// \brief Defines how bindings are processed on recursive matches.
+ /// Defines how bindings are processed on recursive matches.
enum BindKind {
/// Stop at the first match and only bind the first match.
BK_First,
@@ -952,7 +970,7 @@ public:
BK_All
};
- /// \brief Defines which ancestors are considered for a match.
+ /// Defines which ancestors are considered for a match.
enum AncestorMatchMode {
/// All ancestors.
AMM_All,
@@ -963,7 +981,7 @@ public:
virtual ~ASTMatchFinder() = default;
- /// \brief Returns true if the given class is directly or indirectly derived
+ /// Returns true if the given class is directly or indirectly derived
/// from a base type matching \c base.
///
/// A class is considered to be also derived from itself.
@@ -1039,27 +1057,27 @@ protected:
AncestorMatchMode MatchMode) = 0;
};
-/// \brief A type-list implementation.
+/// A type-list implementation.
///
/// A "linked list" of types, accessible by using the ::head and ::tail
/// typedefs.
template <typename... Ts> struct TypeList {}; // Empty sentinel type list.
template <typename T1, typename... Ts> struct TypeList<T1, Ts...> {
- /// \brief The first type on the list.
+ /// The first type on the list.
using head = T1;
- /// \brief A sublist with the tail. ie everything but the head.
+ /// A sublist with the tail. ie everything but the head.
///
/// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the
/// end of the list.
using tail = TypeList<Ts...>;
};
-/// \brief The empty type list.
+/// The empty type list.
using EmptyTypeList = TypeList<>;
-/// \brief Helper meta-function to determine if some type \c T is present or
+/// Helper meta-function to determine if some type \c T is present or
/// a parent type in the list.
template <typename AnyTypeList, typename T>
struct TypeListContainsSuperOf {
@@ -1072,14 +1090,14 @@ struct TypeListContainsSuperOf<EmptyTypeList, T> {
static const bool value = false;
};
-/// \brief A "type list" that contains all types.
+/// A "type list" that contains all types.
///
/// Useful for matchers like \c anything and \c unless.
using AllNodeBaseTypes =
TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
Type, TypeLoc, CXXCtorInitializer>;
-/// \brief Helper meta-function to extract the argument out of a function of
+/// Helper meta-function to extract the argument out of a function of
/// type void(Arg).
///
/// See AST_POLYMORPHIC_SUPPORTED_TYPES for details.
@@ -1088,21 +1106,21 @@ template <class T> struct ExtractFunctionArgMeta<void(T)> {
using type = T;
};
-/// \brief Default type lists for ArgumentAdaptingMatcher matchers.
+/// Default type lists for ArgumentAdaptingMatcher matchers.
using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
using AdaptativeDefaultToTypes =
TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
QualType>;
-/// \brief All types that are supported by HasDeclarationMatcher above.
+/// All types that are supported by HasDeclarationMatcher above.
using HasDeclarationSupportedTypes =
TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
MemberExpr, QualType, RecordType, TagType,
TemplateSpecializationType, TemplateTypeParmType, TypedefType,
- UnresolvedUsingType>;
+ UnresolvedUsingType, ObjCIvarRefExpr>;
-/// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by
+/// Converts a \c Matcher<T> to a matcher of desired type \c To by
/// "adapting" a \c To into a \c T.
///
/// The \c ArgumentAdapterT argument specifies how the adaptation is done.
@@ -1145,7 +1163,7 @@ struct ArgumentAdaptingMatcherFunc {
}
};
-/// \brief A PolymorphicMatcherWithParamN<MatcherT, P1, ..., PN> object can be
+/// A PolymorphicMatcherWithParamN<MatcherT, P1, ..., PN> object can be
/// created from N parameters p1, ..., pN (of type P1, ..., PN) and
/// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN)
/// can be constructed.
@@ -1214,7 +1232,7 @@ private:
const P2 Param2;
};
-/// \brief Matches any instance of the given NodeType.
+/// Matches any instance of the given NodeType.
///
/// This is useful when a matcher syntactically requires a child matcher,
/// but the context doesn't care. See for example: anything().
@@ -1230,7 +1248,7 @@ public:
}
};
-/// \brief A Matcher that allows binding the node it matches to an id.
+/// A Matcher that allows binding the node it matches to an id.
///
/// BindableMatcher provides a \a bind() method that allows binding the
/// matched node to an id if the match was successful.
@@ -1241,7 +1259,7 @@ public:
explicit BindableMatcher(MatcherInterface<T> *Implementation)
: Matcher<T>(Implementation) {}
- /// \brief Returns a matcher that will bind the matched node on a match.
+ /// Returns a matcher that will bind the matched node on a match.
///
/// The returned matcher is equivalent to this matcher, but will
/// bind the matched node on a match.
@@ -1251,7 +1269,7 @@ public:
->template unconditionalConvertTo<T>();
}
- /// \brief Same as Matcher<T>'s conversion operator, but enables binding on
+ /// Same as Matcher<T>'s conversion operator, but enables binding on
/// the returned matcher.
operator DynTypedMatcher() const {
DynTypedMatcher Result = static_cast<const Matcher<T>&>(*this);
@@ -1260,7 +1278,7 @@ public:
}
};
-/// \brief Matches nodes of type T that have child nodes of type ChildT for
+/// Matches nodes of type T that have child nodes of type ChildT for
/// which a specified child matcher matches.
///
/// ChildT must be an AST base type.
@@ -1278,7 +1296,7 @@ public:
}
};
-/// \brief Matches nodes of type T that have child nodes of type ChildT for
+/// Matches nodes of type T that have child nodes of type ChildT for
/// which a specified child matcher matches. ChildT must be an AST base
/// type.
/// As opposed to the HasMatcher, the ForEachMatcher will produce a match
@@ -1301,10 +1319,10 @@ class ForEachMatcher : public WrapperMatcherInterface<T> {
}
};
-/// \brief VariadicOperatorMatcher related types.
+/// VariadicOperatorMatcher related types.
/// @{
-/// \brief Polymorphic matcher object that uses a \c
+/// Polymorphic matcher object that uses a \c
/// DynTypedMatcher::VariadicOperator operator.
///
/// Input matchers can have any type (including other polymorphic matcher
@@ -1333,7 +1351,7 @@ private:
std::tuple<Ps...> Params;
};
-/// \brief Overloaded function object to generate VariadicOperatorMatcher
+/// Overloaded function object to generate VariadicOperatorMatcher
/// objects from arbitrary matchers.
template <unsigned MinCount, unsigned MaxCount>
struct VariadicOperatorMatcherFunc {
@@ -1354,7 +1372,7 @@ inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
return Matcher<T>(*this);
}
-/// \brief Creates a Matcher<T> that matches if all inner matchers match.
+/// Creates a Matcher<T> that matches if all inner matchers match.
template<typename T>
BindableMatcher<T> makeAllOfComposite(
ArrayRef<const Matcher<T> *> InnerMatchers) {
@@ -1380,7 +1398,7 @@ BindableMatcher<T> makeAllOfComposite(
.template unconditionalConvertTo<T>());
}
-/// \brief Creates a Matcher<T> that matches if
+/// Creates a Matcher<T> that matches if
/// T is dyn_cast'able into InnerT and all inner matchers match.
///
/// Returns BindableMatcher, as matchers that use dyn_cast have
@@ -1393,7 +1411,7 @@ BindableMatcher<T> makeDynCastAllOfComposite(
makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
}
-/// \brief Matches nodes of type T that have at least one descendant node of
+/// Matches nodes of type T that have at least one descendant node of
/// type DescendantT for which the given inner matcher matches.
///
/// DescendantT must be an AST base type.
@@ -1413,7 +1431,7 @@ public:
}
};
-/// \brief Matches nodes of type \c T that have a parent node of type \c ParentT
+/// Matches nodes of type \c T that have a parent node of type \c ParentT
/// for which the given inner matcher matches.
///
/// \c ParentT must be an AST base type.
@@ -1433,7 +1451,7 @@ public:
}
};
-/// \brief Matches nodes of type \c T that have at least one ancestor node of
+/// Matches nodes of type \c T that have at least one ancestor node of
/// type \c AncestorT for which the given inner matcher matches.
///
/// \c AncestorT must be an AST base type.
@@ -1453,7 +1471,7 @@ public:
}
};
-/// \brief Matches nodes of type T that have at least one descendant node of
+/// Matches nodes of type T that have at least one descendant node of
/// type DescendantT for which the given inner matcher matches.
///
/// DescendantT must be an AST base type.
@@ -1476,7 +1494,7 @@ public:
}
};
-/// \brief Matches on nodes that have a getValue() method if getValue() equals
+/// Matches on nodes that have a getValue() method if getValue() equals
/// the value the ValueEqualsMatcher was constructed with.
template <typename T, typename ValueT>
class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> {
@@ -1498,7 +1516,7 @@ private:
const ValueT ExpectedValue;
};
-/// \brief Template specializations to easily write matchers for floating point
+/// Template specializations to easily write matchers for floating point
/// literals.
template <>
inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
@@ -1524,7 +1542,7 @@ inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
}
-/// \brief A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
+/// A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
/// variadic functor that takes a number of Matcher<TargetT> and returns a
/// Matcher<SourceT> that matches TargetT nodes that are matched by all of the
/// given matchers, if SourceT can be dynamically casted into TargetT.
@@ -1544,7 +1562,7 @@ public:
VariadicDynCastAllOfMatcher() {}
};
-/// \brief A \c VariadicAllOfMatcher<T> object is a variadic functor that takes
+/// A \c VariadicAllOfMatcher<T> object is a variadic functor that takes
/// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T
/// nodes that are matched by all of the given matchers.
///
@@ -1562,7 +1580,7 @@ public:
VariadicAllOfMatcher() {}
};
-/// \brief Matches nodes of type \c TLoc for which the inner
+/// Matches nodes of type \c TLoc for which the inner
/// \c Matcher<T> matches.
template <typename TLoc, typename T>
class LocMatcher : public WrapperMatcherInterface<TLoc> {
@@ -1584,7 +1602,7 @@ private:
}
};
-/// \brief Matches \c TypeLocs based on an inner matcher matching a certain
+/// Matches \c TypeLocs based on an inner matcher matching a certain
/// \c QualType.
///
/// Used to implement the \c loc() matcher.
@@ -1602,7 +1620,7 @@ public:
}
};
-/// \brief Matches nodes of type \c T for which the inner matcher matches on a
+/// Matches nodes of type \c T for which the inner matcher matches on a
/// another node of type \c T that can be reached using a given traverse
/// function.
template <typename T>
@@ -1626,7 +1644,7 @@ private:
QualType (T::*TraverseFunction)() const;
};
-/// \brief Matches nodes of type \c T in a ..Loc hierarchy, for which the inner
+/// Matches nodes of type \c T in a ..Loc hierarchy, for which the inner
/// matcher matches on a another node of type \c T that can be reached using a
/// given traverse function.
template <typename T>
@@ -1650,7 +1668,7 @@ private:
TypeLoc (T::*TraverseFunction)() const;
};
-/// \brief Converts a \c Matcher<InnerT> to a \c Matcher<OuterT>, where
+/// Converts a \c Matcher<InnerT> to a \c Matcher<OuterT>, where
/// \c OuterT is any type that is supported by \c Getter.
///
/// \code Getter<OuterT>::value() \endcode returns a
@@ -1688,7 +1706,7 @@ private:
const Matcher<InnerTBase> InnerMatcher;
};
-/// \brief A simple memoizer of T(*)() functions.
+/// A simple memoizer of T(*)() functions.
///
/// It will call the passed 'Func' template parameter at most once.
/// Used to support AST_MATCHER_FUNCTION() macro.
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h
index 6a48da821a53e..3080f86699b56 100644
--- a/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ b/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -50,7 +50,7 @@
#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
-/// \brief AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... }
+/// AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... }
/// defines a zero parameter function named DefineMatcher() that returns a
/// ReturnType object.
#define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) \
@@ -61,7 +61,7 @@
} \
inline ReturnType DefineMatcher##_getInstance()
-/// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
+/// AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
/// ... }
/// defines a single-parameter function named DefineMatcher() that returns a
/// ReturnType object.
@@ -81,7 +81,7 @@
typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &); \
inline ReturnType DefineMatcher(ParamType const &Param)
-/// \brief AST_MATCHER(Type, DefineMatcher) { ... }
+/// AST_MATCHER(Type, DefineMatcher) { ... }
/// defines a zero parameter function named DefineMatcher() that returns a
/// Matcher<Type> object.
///
@@ -113,7 +113,7 @@
::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
-/// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
+/// AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
/// defines a single-parameter function named DefineMatcher() that returns a
/// Matcher<Type> object.
///
@@ -159,7 +159,7 @@
::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
-/// \brief AST_MATCHER_P2(
+/// AST_MATCHER_P2(
/// Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
/// defines a two-parameter function named DefineMatcher() that returns a
/// Matcher<Type> object.
@@ -211,7 +211,7 @@
::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
-/// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
+/// Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
/// macros.
///
/// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
@@ -222,7 +222,7 @@
#define AST_POLYMORPHIC_SUPPORTED_TYPES(...) \
void(::clang::ast_matchers::internal::TypeList<__VA_ARGS__>)
-/// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
+/// AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
/// defines a single-parameter function named DefineMatcher() that is
/// polymorphic in the return type.
///
@@ -252,7 +252,7 @@
::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
-/// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
+/// AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
/// defines a single-parameter function named DefineMatcher() that is
/// polymorphic in the return type.
///
@@ -305,7 +305,7 @@
::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \
const
-/// \brief AST_POLYMORPHIC_MATCHER_P2(
+/// AST_POLYMORPHIC_MATCHER_P2(
/// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
/// defines a two-parameter function named matcher() that is polymorphic in
/// the return type.
@@ -359,11 +359,6 @@
::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \
const
-/// \brief Creates a variadic matcher for both a specific \c Type as well as
-/// the corresponding \c TypeLoc.
-#define AST_TYPE_MATCHER(NodeType, MatcherName) \
- const ::clang::ast_matchers::internal::VariadicDynCastAllOfMatcher< \
- Type, NodeType> MatcherName
// FIXME: add a matcher for TypeLoc derived classes using its custom casting
// API (no longer dyn_cast) if/when we need such matching
@@ -388,7 +383,7 @@
::clang::ast_matchers::internal::TypeTraverseMatcher, \
ReturnTypesF>::Func MatcherName
-/// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
+/// AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
/// the matcher \c MatcherName that can be used to traverse from one \c Type
/// to another.
///
@@ -431,7 +426,7 @@
ReturnTypesF>::Func MatcherName##Loc; \
AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)
-/// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
+/// AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
/// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \
namespace internal { \
diff --git a/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
index 908fa0db622d0..ccd9590f4bb4a 100644
--- a/include/clang/ASTMatchers/Dynamic/Diagnostics.h
+++ b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Diagnostics class to manage error messages.
+/// Diagnostics class to manage error messages.
///
//===----------------------------------------------------------------------===//
@@ -39,7 +39,7 @@ struct SourceRange {
SourceLocation End;
};
-/// \brief A VariantValue instance annotated with its parser context.
+/// A VariantValue instance annotated with its parser context.
struct ParserValue {
ParserValue() : Text(), Range(), Value() {}
StringRef Text;
@@ -47,16 +47,16 @@ struct ParserValue {
VariantValue Value;
};
-/// \brief Helper class to manage error messages.
+/// Helper class to manage error messages.
class Diagnostics {
public:
- /// \brief Parser context types.
+ /// Parser context types.
enum ContextType {
CT_MatcherArg = 0,
CT_MatcherConstruct = 1
};
- /// \brief All errors from the system.
+ /// All errors from the system.
enum ErrorType {
ET_None = 0,
@@ -80,7 +80,7 @@ public:
ET_ParserOverloadedType = 110
};
- /// \brief Helper stream class.
+ /// Helper stream class.
class ArgStream {
public:
ArgStream(std::vector<std::string> *Out) : Out(Out) {}
@@ -93,7 +93,7 @@ public:
std::vector<std::string> *Out;
};
- /// \brief Class defining a parser context.
+ /// Class defining a parser context.
///
/// Used by the parser to specify (possibly recursive) contexts where the
/// parsing/construction can fail. Any error triggered within a context will
@@ -101,11 +101,11 @@ public:
/// This class should be used as a RAII instance in the stack.
struct Context {
public:
- /// \brief About to call the constructor for a matcher.
+ /// About to call the constructor for a matcher.
enum ConstructMatcherEnum { ConstructMatcher };
Context(ConstructMatcherEnum, Diagnostics *Error, StringRef MatcherName,
SourceRange MatcherRange);
- /// \brief About to recurse into parsing one argument for a matcher.
+ /// About to recurse into parsing one argument for a matcher.
enum MatcherArgEnum { MatcherArg };
Context(MatcherArgEnum, Diagnostics *Error, StringRef MatcherName,
SourceRange MatcherRange, unsigned ArgNumber);
@@ -115,7 +115,7 @@ public:
Diagnostics *const Error;
};
- /// \brief Context for overloaded matcher construction.
+ /// Context for overloaded matcher construction.
///
/// This context will take care of merging all errors that happen within it
/// as "candidate" overloads for the same matcher.
@@ -124,7 +124,7 @@ public:
OverloadContext(Diagnostics* Error);
~OverloadContext();
- /// \brief Revert all errors that happened within this context.
+ /// Revert all errors that happened within this context.
void revertErrors();
private:
@@ -132,21 +132,21 @@ public:
unsigned BeginIndex;
};
- /// \brief Add an error to the diagnostics.
+ /// Add an error to the diagnostics.
///
/// All the context information will be kept on the error message.
/// \return a helper class to allow the caller to pass the arguments for the
/// error message, using the << operator.
ArgStream addError(SourceRange Range, ErrorType Error);
- /// \brief Information stored for one frame of the context.
+ /// Information stored for one frame of the context.
struct ContextFrame {
ContextType Type;
SourceRange Range;
std::vector<std::string> Args;
};
- /// \brief Information stored for each error found.
+ /// Information stored for each error found.
struct ErrorContent {
std::vector<ContextFrame> ContextStack;
struct Message {
@@ -158,20 +158,20 @@ public:
};
ArrayRef<ErrorContent> errors() const { return Errors; }
- /// \brief Returns a simple string representation of each error.
+ /// Returns a simple string representation of each error.
///
/// Each error only shows the error message without any context.
void printToStream(llvm::raw_ostream &OS) const;
std::string toString() const;
- /// \brief Returns the full string representation of each error.
+ /// Returns the full string representation of each error.
///
/// Each error message contains the full context.
void printToStreamFull(llvm::raw_ostream &OS) const;
std::string toStringFull() const;
private:
- /// \brief Helper function used by the constructors of ContextFrame.
+ /// Helper function used by the constructors of ContextFrame.
ArgStream pushContextFrame(ContextType Type, SourceRange Range);
std::vector<ContextFrame> ContextStack;
diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h
index e8fcf0a9d6ccd..907db69529d28 100644
--- a/include/clang/ASTMatchers/Dynamic/Parser.h
+++ b/include/clang/ASTMatchers/Dynamic/Parser.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Simple matcher expression parser.
+/// Simple matcher expression parser.
///
/// The parser understands matcher expressions of the form:
/// MatcherName(Arg0, Arg1, ..., ArgN)
@@ -52,10 +52,10 @@ namespace dynamic {
class Diagnostics;
-/// \brief Matcher expression parser.
+/// Matcher expression parser.
class Parser {
public:
- /// \brief Interface to connect the parser with the registry and more.
+ /// Interface to connect the parser with the registry and more.
///
/// The parser uses the Sema instance passed into
/// parseMatcherExpression() to handle all matcher tokens. The simplest
@@ -69,7 +69,7 @@ public:
public:
virtual ~Sema();
- /// \brief Process a matcher expression.
+ /// Process a matcher expression.
///
/// All the arguments passed here have already been processed.
///
@@ -92,7 +92,7 @@ public:
ArrayRef<ParserValue> Args,
Diagnostics *Error) = 0;
- /// \brief Look up a matcher by name.
+ /// Look up a matcher by name.
///
/// \param MatcherName The matcher name found by the parser.
///
@@ -101,7 +101,7 @@ public:
virtual llvm::Optional<MatcherCtor>
lookupMatcherCtor(StringRef MatcherName) = 0;
- /// \brief Compute the list of completion types for \p Context.
+ /// Compute the list of completion types for \p Context.
///
/// Each element of \p Context represents a matcher invocation, going from
/// outermost to innermost. Elements are pairs consisting of a reference to
@@ -112,7 +112,7 @@ public:
virtual std::vector<ArgKind> getAcceptedCompletionTypes(
llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);
- /// \brief Compute the list of completions that match any of
+ /// Compute the list of completions that match any of
/// \p AcceptedTypes.
///
/// \param AcceptedTypes All types accepted for this completion.
@@ -125,7 +125,7 @@ public:
getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes);
};
- /// \brief Sema implementation that uses the matcher registry to process the
+ /// Sema implementation that uses the matcher registry to process the
/// tokens.
class RegistrySema : public Parser::Sema {
public:
@@ -149,7 +149,7 @@ public:
using NamedValueMap = llvm::StringMap<VariantValue>;
- /// \brief Parse a matcher expression.
+ /// Parse a matcher expression.
///
/// \param MatcherCode The matcher expression to parse.
///
@@ -178,7 +178,7 @@ public:
return parseMatcherExpression(MatcherCode, nullptr, Error);
}
- /// \brief Parse an expression.
+ /// Parse an expression.
///
/// Parses any expression supported by this parser. In general, the
/// \c parseMatcherExpression function is a better approach to get a matcher
@@ -202,7 +202,7 @@ public:
return parseExpression(Code, nullptr, Value, Error);
}
- /// \brief Complete an expression at the given offset.
+ /// Complete an expression at the given offset.
///
/// \param S The Sema instance that will help the parser
/// construct the matchers. If null, it uses the default registry.
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
index 277491250db8f..ad8628b4b0d97 100644
--- a/include/clang/ASTMatchers/Dynamic/Registry.h
+++ b/include/clang/ASTMatchers/Dynamic/Registry.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Registry of all known matchers.
+/// Registry of all known matchers.
///
/// The registry provides a generic interface to construct any matcher by name.
//
@@ -49,13 +49,13 @@ struct MatcherCompletion {
return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
}
- /// \brief The text to type to select this matcher.
+ /// The text to type to select this matcher.
std::string TypedText;
- /// \brief The "declaration" of the matcher, with type information.
+ /// The "declaration" of the matcher, with type information.
std::string MatcherDecl;
- /// \brief Value corresponding to the "specificity" of the converted matcher.
+ /// Value corresponding to the "specificity" of the converted matcher.
///
/// Zero specificity indicates that this conversion would produce a trivial
/// matcher that will either always or never match.
@@ -67,13 +67,13 @@ class Registry {
public:
Registry() = delete;
- /// \brief Look up a matcher in the registry by name,
+ /// Look up a matcher in the registry by name,
///
/// \return An opaque value which may be used to refer to the matcher
/// constructor, or Optional<MatcherCtor>() if not found.
static llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName);
- /// \brief Compute the list of completion types for \p Context.
+ /// Compute the list of completion types for \p Context.
///
/// Each element of \p Context represents a matcher invocation, going from
/// outermost to innermost. Elements are pairs consisting of a reference to
@@ -84,7 +84,7 @@ public:
static std::vector<ArgKind> getAcceptedCompletionTypes(
llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);
- /// \brief Compute the list of completions that match any of
+ /// Compute the list of completions that match any of
/// \p AcceptedTypes.
///
/// \param AcceptedTypes All types accepted for this completion.
@@ -96,7 +96,7 @@ public:
static std::vector<MatcherCompletion>
getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes);
- /// \brief Construct a matcher from the registry.
+ /// Construct a matcher from the registry.
///
/// \param Ctor The matcher constructor to instantiate.
///
@@ -116,7 +116,7 @@ public:
ArrayRef<ParserValue> Args,
Diagnostics *Error);
- /// \brief Construct a matcher from the registry and bind it.
+ /// Construct a matcher from the registry and bind it.
///
/// Similar the \c constructMatcher() above, but it then tries to bind the
/// matcher to the specified \c BindID.
diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h
index f9efe0f16f437..45ac3cadf6857 100644
--- a/include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Polymorphic value type.
+/// Polymorphic value type.
///
/// Supports all the types required for dynamic Matcher construction.
/// Used by the registry to construct matchers in a generic way.
@@ -28,7 +28,7 @@ namespace clang {
namespace ast_matchers {
namespace dynamic {
-/// \brief Kind identifier.
+/// Kind identifier.
///
/// It supports all types that VariantValue can contain.
class ArgKind {
@@ -40,10 +40,10 @@ class ArgKind {
AK_Unsigned,
AK_String
};
- /// \brief Constructor for non-matcher types.
+ /// Constructor for non-matcher types.
ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); }
- /// \brief Constructor for matcher types.
+ /// Constructor for matcher types.
ArgKind(ast_type_traits::ASTNodeKind MatcherKind)
: K(AK_Matcher), MatcherKind(MatcherKind) {}
@@ -53,7 +53,7 @@ class ArgKind {
return MatcherKind;
}
- /// \brief Determines if this type can be converted to \p To.
+ /// Determines if this type can be converted to \p To.
///
/// \param To the requested destination type.
///
@@ -67,7 +67,7 @@ class ArgKind {
return K < Other.K;
}
- /// \brief String representation of the type.
+ /// String representation of the type.
std::string asString() const;
private:
@@ -77,7 +77,7 @@ private:
using ast_matchers::internal::DynTypedMatcher;
-/// \brief A variant matcher object.
+/// A variant matcher object.
///
/// The purpose of this object is to abstract simple and polymorphic matchers
/// into a single object type.
@@ -91,7 +91,7 @@ using ast_matchers::internal::DynTypedMatcher;
/// - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if
/// the underlying matcher(s) can unambiguously return a Matcher<T>.
class VariantMatcher {
- /// \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher.
+ /// Methods that depend on T from hasTypedMatcher/getTypedMatcher.
class MatcherOps {
public:
MatcherOps(ast_type_traits::ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
@@ -99,12 +99,12 @@ class VariantMatcher {
bool canConstructFrom(const DynTypedMatcher &Matcher,
bool &IsExactMatch) const;
- /// \brief Convert \p Matcher the destination type and return it as a new
+ /// Convert \p Matcher the destination type and return it as a new
/// DynTypedMatcher.
virtual DynTypedMatcher
convertMatcher(const DynTypedMatcher &Matcher) const = 0;
- /// \brief Constructs a variadic typed matcher from \p InnerMatchers.
+ /// Constructs a variadic typed matcher from \p InnerMatchers.
/// Will try to convert each inner matcher to the destination type and
/// return llvm::None if it fails to do so.
llvm::Optional<DynTypedMatcher>
@@ -118,7 +118,7 @@ class VariantMatcher {
ast_type_traits::ASTNodeKind NodeKind;
};
- /// \brief Payload interface to be specialized by each matcher type.
+ /// Payload interface to be specialized by each matcher type.
///
/// It follows a similar interface as VariantMatcher itself.
class Payload {
@@ -133,39 +133,39 @@ class VariantMatcher {
};
public:
- /// \brief A null matcher.
+ /// A null matcher.
VariantMatcher();
- /// \brief Clones the provided matcher.
+ /// Clones the provided matcher.
static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher);
- /// \brief Clones the provided matchers.
+ /// Clones the provided matchers.
///
/// They should be the result of a polymorphic matcher.
static VariantMatcher
PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
- /// \brief Creates a 'variadic' operator matcher.
+ /// Creates a 'variadic' operator matcher.
///
/// It will bind to the appropriate type on getTypedMatcher<T>().
static VariantMatcher
VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op,
std::vector<VariantMatcher> Args);
- /// \brief Makes the matcher the "null" matcher.
+ /// Makes the matcher the "null" matcher.
void reset();
- /// \brief Whether the matcher is null.
+ /// Whether the matcher is null.
bool isNull() const { return !Value; }
- /// \brief Return a single matcher, if there is no ambiguity.
+ /// Return a single matcher, if there is no ambiguity.
///
/// \returns the matcher, if there is only one matcher. An empty Optional, if
/// the underlying matcher is a polymorphic matcher with more than one
/// representation.
llvm::Optional<DynTypedMatcher> getSingleMatcher() const;
- /// \brief Determines if the contained matcher can be converted to
+ /// Determines if the contained matcher can be converted to
/// \c Matcher<T>.
///
/// For the Single case, it returns true if it can be converted to
@@ -179,7 +179,7 @@ public:
return Value->getTypedMatcher(TypedMatcherOps<T>()).hasValue();
}
- /// \brief Determines if the contained matcher can be converted to \p Kind.
+ /// Determines if the contained matcher can be converted to \p Kind.
///
/// \param Kind the requested destination type.
///
@@ -192,7 +192,7 @@ public:
return false;
}
- /// \brief Return this matcher as a \c Matcher<T>.
+ /// Return this matcher as a \c Matcher<T>.
///
/// Handles the different types (Single, Polymorphic) accordingly.
/// Asserts that \c hasTypedMatcher<T>() is true.
@@ -203,7 +203,7 @@ public:
->template convertTo<T>();
}
- /// \brief String representation of the type of the value.
+ /// String representation of the type of the value.
///
/// If the underlying matcher is a polymorphic one, the string will show all
/// the types.
@@ -234,7 +234,7 @@ struct VariantMatcher::TypedMatcherOps final : VariantMatcher::MatcherOps {
}
};
-/// \brief Variant value class.
+/// Variant value class.
///
/// Basically, a tagged union with value type semantics.
/// It is used by the registry as the return value and argument type for the
@@ -256,46 +256,46 @@ public:
~VariantValue();
VariantValue &operator=(const VariantValue &Other);
- /// \brief Specific constructors for each supported type.
+ /// Specific constructors for each supported type.
VariantValue(bool Boolean);
VariantValue(double Double);
VariantValue(unsigned Unsigned);
VariantValue(StringRef String);
VariantValue(const VariantMatcher &Matchers);
- /// \brief Constructs an \c unsigned value (disambiguation from bool).
+ /// Constructs an \c unsigned value (disambiguation from bool).
VariantValue(int Signed) : VariantValue(static_cast<unsigned>(Signed)) {}
- /// \brief Returns true iff this is not an empty value.
+ /// Returns true iff this is not an empty value.
explicit operator bool() const { return hasValue(); }
bool hasValue() const { return Type != VT_Nothing; }
- /// \brief Boolean value functions.
+ /// Boolean value functions.
bool isBoolean() const;
bool getBoolean() const;
void setBoolean(bool Boolean);
- /// \brief Double value functions.
+ /// Double value functions.
bool isDouble() const;
double getDouble() const;
void setDouble(double Double);
- /// \brief Unsigned value functions.
+ /// Unsigned value functions.
bool isUnsigned() const;
unsigned getUnsigned() const;
void setUnsigned(unsigned Unsigned);
- /// \brief String value functions.
+ /// String value functions.
bool isString() const;
const std::string &getString() const;
void setString(StringRef String);
- /// \brief Matcher value functions.
+ /// Matcher value functions.
bool isMatcher() const;
const VariantMatcher &getMatcher() const;
void setMatcher(const VariantMatcher &Matcher);
- /// \brief Determines if the contained value can be converted to \p Kind.
+ /// Determines if the contained value can be converted to \p Kind.
///
/// \param Kind the requested destination type.
///
@@ -303,7 +303,7 @@ public:
/// conversion.
bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const;
- /// \brief Determines if the contained value can be converted to any kind
+ /// Determines if the contained value can be converted to any kind
/// in \p Kinds.
///
/// \param Kinds the requested destination types.
@@ -313,13 +313,13 @@ public:
/// conversions.
bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const;
- /// \brief String representation of the type of the value.
+ /// String representation of the type of the value.
std::string getTypeAsString() const;
private:
void reset();
- /// \brief All supported value types.
+ /// All supported value types.
enum ValueType {
VT_Nothing,
VT_Boolean,
@@ -329,7 +329,7 @@ private:
VT_Matcher
};
- /// \brief All supported value types.
+ /// All supported value types.
union AllValues {
unsigned Unsigned;
double Double;
diff --git a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
index cc14c7bd33dbc..da59514c4fa6e 100644
--- a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
+++ b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
@@ -1,4 +1,4 @@
-//==- CFGReachabilityAnalysis.h - Basic reachability analysis ----*- C++ -*-==//
+//===- CFGReachabilityAnalysis.h - Basic reachability analysis --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -30,10 +30,12 @@ class CFGBlock;
// from the destination node and cache the results to prevent work
// duplication.
class CFGReverseBlockReachabilityAnalysis {
- typedef llvm::BitVector ReachableSet;
- typedef llvm::DenseMap<unsigned, ReachableSet> ReachableMap;
+ using ReachableSet = llvm::BitVector;
+ using ReachableMap = llvm::DenseMap<unsigned, ReachableSet>;
+
ReachableSet analyzed;
ReachableMap reachable;
+
public:
CFGReverseBlockReachabilityAnalysis(const CFG &cfg);
@@ -44,6 +46,6 @@ private:
void mapReachability(const CFGBlock *Dst);
};
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_CFGREACHABILITYANALYSIS_H
diff --git a/include/clang/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h
index 5ba42b475c830..6003d665fd88b 100644
--- a/include/clang/Analysis/Analyses/Consumed.h
+++ b/include/clang/Analysis/Analyses/Consumed.h
@@ -1,4 +1,4 @@
-//===- Consumed.h ----------------------------------------------*- C++ --*-===//
+//===- Consumed.h -----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,16 +15,32 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_CONSUMED_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_CONSUMED_H
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/StmtCXX.h"
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
-#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include <list>
+#include <memory>
+#include <utility>
+#include <vector>
namespace clang {
+
+class AnalysisDeclContext;
+class CXXBindTemporaryExpr;
+class FunctionDecl;
+class PostOrderCFGView;
+class Stmt;
+class VarDecl;
+
namespace consumed {
+ class ConsumedStmtVisitor;
+
enum ConsumedState {
// No state information for the given variable.
CS_None,
@@ -34,22 +50,18 @@ namespace consumed {
CS_Consumed
};
- class ConsumedStmtVisitor;
-
- typedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes;
- typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag;
- typedef std::list<DelayedDiag> DiagList;
+ using OptionalNotes = SmallVector<PartialDiagnosticAt, 1>;
+ using DelayedDiag = std::pair<PartialDiagnosticAt, OptionalNotes>;
+ using DiagList = std::list<DelayedDiag>;
class ConsumedWarningsHandlerBase {
-
public:
-
virtual ~ConsumedWarningsHandlerBase();
- /// \brief Emit the warnings and notes left by the analysis.
+ /// Emit the warnings and notes left by the analysis.
virtual void emitDiagnostics() {}
- /// \brief Warn that a variable's state doesn't match at the entry and exit
+ /// Warn that a variable's state doesn't match at the entry and exit
/// of a loop.
///
/// \param Loc -- The location of the end of the loop.
@@ -59,7 +71,7 @@ namespace consumed {
virtual void warnLoopStateMismatch(SourceLocation Loc,
StringRef VariableName) {}
- /// \brief Warn about parameter typestate mismatches upon return.
+ /// Warn about parameter typestate mismatches upon return.
///
/// \param Loc -- The SourceLocation of the return statement.
///
@@ -80,7 +92,7 @@ namespace consumed {
// FIXME: This can be removed when the attr propagation fix for templated
// classes lands.
- /// \brief Warn about return typestates set for unconsumable types.
+ /// Warn about return typestates set for unconsumable types.
///
/// \param Loc -- The location of the attributes.
///
@@ -88,7 +100,7 @@ namespace consumed {
virtual void warnReturnTypestateForUnconsumableType(SourceLocation Loc,
StringRef TypeName) {}
- /// \brief Warn about return typestate mismatches.
+ /// Warn about return typestate mismatches.
///
/// \param Loc -- The SourceLocation of the return statement.
///
@@ -101,7 +113,7 @@ namespace consumed {
StringRef ExpectedState,
StringRef ObservedState) {}
- /// \brief Warn about use-while-consumed errors.
+ /// Warn about use-while-consumed errors.
/// \param MethodName -- The name of the method that was incorrectly
/// invoked.
///
@@ -112,7 +124,7 @@ namespace consumed {
StringRef State,
SourceLocation Loc) {}
- /// \brief Warn about use-while-consumed errors.
+ /// Warn about use-while-consumed errors.
/// \param MethodName -- The name of the method that was incorrectly
/// invoked.
///
@@ -129,66 +141,64 @@ namespace consumed {
};
class ConsumedStateMap {
-
- typedef llvm::DenseMap<const VarDecl *, ConsumedState> VarMapType;
- typedef llvm::DenseMap<const CXXBindTemporaryExpr *, ConsumedState>
- TmpMapType;
+ using VarMapType = llvm::DenseMap<const VarDecl *, ConsumedState>;
+ using TmpMapType =
+ llvm::DenseMap<const CXXBindTemporaryExpr *, ConsumedState>;
protected:
-
- bool Reachable;
- const Stmt *From;
+ bool Reachable = true;
+ const Stmt *From = nullptr;
VarMapType VarMap;
TmpMapType TmpMap;
public:
- ConsumedStateMap() : Reachable(true), From(nullptr) {}
+ ConsumedStateMap() = default;
ConsumedStateMap(const ConsumedStateMap &Other)
- : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap),
- TmpMap() {}
+ : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap),
+ TmpMap() {}
- /// \brief Warn if any of the parameters being tracked are not in the state
+ /// Warn if any of the parameters being tracked are not in the state
/// they were declared to be in upon return from a function.
void checkParamsForReturnTypestate(SourceLocation BlameLoc,
ConsumedWarningsHandlerBase &WarningsHandler) const;
- /// \brief Clear the TmpMap.
+ /// Clear the TmpMap.
void clearTemporaries();
- /// \brief Get the consumed state of a given variable.
+ /// Get the consumed state of a given variable.
ConsumedState getState(const VarDecl *Var) const;
- /// \brief Get the consumed state of a given temporary value.
+ /// Get the consumed state of a given temporary value.
ConsumedState getState(const CXXBindTemporaryExpr *Tmp) const;
- /// \brief Merge this state map with another map.
+ /// Merge this state map with another map.
void intersect(const ConsumedStateMap &Other);
void intersectAtLoopHead(const CFGBlock *LoopHead, const CFGBlock *LoopBack,
const ConsumedStateMap *LoopBackStates,
ConsumedWarningsHandlerBase &WarningsHandler);
- /// \brief Return true if this block is reachable.
+ /// Return true if this block is reachable.
bool isReachable() const { return Reachable; }
- /// \brief Mark the block as unreachable.
+ /// Mark the block as unreachable.
void markUnreachable();
- /// \brief Set the source for a decision about the branching of states.
+ /// Set the source for a decision about the branching of states.
/// \param Source -- The statement that was the origin of a branching
/// decision.
void setSource(const Stmt *Source) { this->From = Source; }
- /// \brief Set the consumed state of a given variable.
+ /// Set the consumed state of a given variable.
void setState(const VarDecl *Var, ConsumedState State);
- /// \brief Set the consumed state of a given temporary value.
+ /// Set the consumed state of a given temporary value.
void setState(const CXXBindTemporaryExpr *Tmp, ConsumedState State);
- /// \brief Remove the temporary value from our state map.
+ /// Remove the temporary value from our state map.
void remove(const CXXBindTemporaryExpr *Tmp);
- /// \brief Tests to see if there is a mismatch in the states stored in two
+ /// Tests to see if there is a mismatch in the states stored in two
/// maps.
///
/// \param Other -- The second map to compare against.
@@ -205,10 +215,8 @@ namespace consumed {
ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph)
: StateMapsArray(NumBlocks), VisitOrder(NumBlocks, 0) {
unsigned int VisitOrderCounter = 0;
- for (PostOrderCFGView::iterator BI = SortedGraph->begin(),
- BE = SortedGraph->end(); BI != BE; ++BI) {
- VisitOrder[(*BI)->getBlockID()] = VisitOrderCounter++;
- }
+ for (const auto BI : *SortedGraph)
+ VisitOrder[BI->getBlockID()] = VisitOrderCounter++;
}
bool allBackEdgesVisited(const CFGBlock *CurrBlock,
@@ -231,7 +239,6 @@ namespace consumed {
/// A class that handles the analysis of uniqueness violations.
class ConsumedAnalyzer {
-
ConsumedBlockInfo BlockInfo;
std::unique_ptr<ConsumedStateMap> CurrStates;
@@ -243,7 +250,6 @@ namespace consumed {
const ConsumedStmtVisitor &Visitor);
public:
-
ConsumedWarningsHandlerBase &WarningsHandler;
ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler)
@@ -251,7 +257,7 @@ namespace consumed {
ConsumedState getExpectedReturnState() const { return ExpectedReturnState; }
- /// \brief Check a function's CFG for consumed violations.
+ /// Check a function's CFG for consumed violations.
///
/// We traverse the blocks in the CFG, keeping track of the state of each
/// value who's type has uniquness annotations. If methods are invoked in
@@ -259,6 +265,9 @@ namespace consumed {
/// exactly once.
void run(AnalysisDeclContext &AC);
};
-}} // end namespace clang::consumed
-#endif
+} // namespace consumed
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_CONSUMED_H
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
index 6cb161ab37c8a..a9cdc5560bc07 100644
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -1,4 +1,4 @@
-//==- Dominators.h - Implementation of dominators tree for Clang CFG C++ -*-==//
+//- Dominators.h - Implementation of dominators tree for Clang CFG -*- C++ -*-//
//
// The LLVM Compiler Infrastructure
//
@@ -16,29 +16,35 @@
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/CFG.h"
+#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/Support/GenericDomTree.h"
-#include "llvm/Support/GenericDomTreeConstruction.h"
+#include "llvm/Support/GenericDomTreeConstruction.h"
+#include "llvm/Support/raw_ostream.h"
// FIXME: There is no good reason for the domtree to require a print method
// which accepts an LLVM Module, so remove this (and the method's argument that
// needs it) when that is fixed.
+
namespace llvm {
+
class Module;
-}
+
+} // namespace llvm
namespace clang {
-class CFGBlock;
-typedef llvm::DomTreeNodeBase<CFGBlock> DomTreeNode;
+using DomTreeNode = llvm::DomTreeNodeBase<CFGBlock>;
-/// \brief Concrete subclass of DominatorTreeBase for Clang
+/// Concrete subclass of DominatorTreeBase for Clang
/// This class implements the dominators tree functionality given a Clang CFG.
///
class DominatorTree : public ManagedAnalysis {
virtual void anchor();
+
public:
- llvm::DomTreeBase<CFGBlock>* DT;
+ llvm::DomTreeBase<CFGBlock> *DT;
DominatorTree() {
DT = new llvm::DomTreeBase<CFGBlock>();
@@ -48,23 +54,21 @@ public:
llvm::DomTreeBase<CFGBlock>& getBase() { return *DT; }
- /// \brief This method returns the root CFGBlock of the dominators tree.
- ///
- inline CFGBlock *getRoot() const {
+ /// This method returns the root CFGBlock of the dominators tree.
+ CFGBlock *getRoot() const {
return DT->getRoot();
}
- /// \brief This method returns the root DomTreeNode, which is the wrapper
+ /// This method returns the root DomTreeNode, which is the wrapper
/// for CFGBlock.
- inline DomTreeNode *getRootNode() const {
+ DomTreeNode *getRootNode() const {
return DT->getRootNode();
}
- /// \brief This method compares two dominator trees.
+ /// This method compares two dominator trees.
/// The method returns false if the other dominator tree matches this
/// dominator tree, otherwise returns true.
- ///
- inline bool compare(DominatorTree &Other) const {
+ bool compare(DominatorTree &Other) const {
DomTreeNode *R = getRootNode();
DomTreeNode *OtherR = Other.getRootNode();
@@ -77,17 +81,15 @@ public:
return false;
}
- /// \brief This method builds the dominator tree for a given CFG
+ /// This method builds the dominator tree for a given CFG
/// The CFG information is passed via AnalysisDeclContext
- ///
void buildDominatorTree(AnalysisDeclContext &AC) {
cfg = AC.getCFG();
DT->recalculate(*cfg);
}
- /// \brief This method dumps immediate dominators for each block,
+ /// This method dumps immediate dominators for each block,
/// mainly used for debug purposes.
- ///
void dump() {
llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n";
for (CFG::const_iterator I = cfg->begin(),
@@ -102,55 +104,48 @@ public:
}
}
- /// \brief This method tests if one CFGBlock dominates the other.
+ /// This method tests if one CFGBlock dominates the other.
/// The method return true if A dominates B, false otherwise.
/// Note a block always dominates itself.
- ///
- inline bool dominates(const CFGBlock* A, const CFGBlock* B) const {
+ bool dominates(const CFGBlock *A, const CFGBlock *B) const {
return DT->dominates(A, B);
}
- /// \brief This method tests if one CFGBlock properly dominates the other.
+ /// This method tests if one CFGBlock properly dominates the other.
/// The method return true if A properly dominates B, false otherwise.
- ///
- bool properlyDominates(const CFGBlock*A, const CFGBlock*B) const {
+ bool properlyDominates(const CFGBlock *A, const CFGBlock *B) const {
return DT->properlyDominates(A, B);
}
- /// \brief This method finds the nearest common dominator CFG block
+ /// This method finds the nearest common dominator CFG block
/// for CFG block A and B. If there is no such block then return NULL.
- ///
- inline CFGBlock *findNearestCommonDominator(CFGBlock *A, CFGBlock *B) {
+ CFGBlock *findNearestCommonDominator(CFGBlock *A, CFGBlock *B) {
return DT->findNearestCommonDominator(A, B);
}
- inline const CFGBlock *findNearestCommonDominator(const CFGBlock *A,
- const CFGBlock *B) {
+ const CFGBlock *findNearestCommonDominator(const CFGBlock *A,
+ const CFGBlock *B) {
return DT->findNearestCommonDominator(A, B);
}
- /// \brief This method is used to update the dominator
+ /// This method is used to update the dominator
/// tree information when a node's immediate dominator changes.
- ///
- inline void changeImmediateDominator(CFGBlock *N, CFGBlock *NewIDom) {
+ void changeImmediateDominator(CFGBlock *N, CFGBlock *NewIDom) {
DT->changeImmediateDominator(N, NewIDom);
}
- /// \brief This method tests if the given CFGBlock can be reachable from root.
+ /// This method tests if the given CFGBlock can be reachable from root.
/// Returns true if reachable, false otherwise.
- ///
bool isReachableFromEntry(const CFGBlock *A) {
return DT->isReachableFromEntry(A);
}
- /// \brief This method releases the memory held by the dominator tree.
- ///
+ /// This method releases the memory held by the dominator tree.
virtual void releaseMemory() {
DT->releaseMemory();
}
- /// \brief This method converts the dominator tree to human readable form.
- ///
+ /// This method converts the dominator tree to human readable form.
virtual void print(raw_ostream &OS, const llvm::Module* M= nullptr) const {
DT->print(OS);
}
@@ -159,23 +154,24 @@ private:
CFG *cfg;
};
-} // end namespace clang
+} // namespace clang
//===-------------------------------------
/// DominatorTree GraphTraits specialization so the DominatorTree can be
/// iterable by generic graph iterators.
///
namespace llvm {
+
template <> struct GraphTraits< ::clang::DomTreeNode* > {
- typedef ::clang::DomTreeNode *NodeRef;
- typedef ::clang::DomTreeNode::iterator ChildIteratorType;
+ using NodeRef = ::clang::DomTreeNode *;
+ using ChildIteratorType = ::clang::DomTreeNode::iterator;
static NodeRef getEntryNode(NodeRef N) { return N; }
static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
static ChildIteratorType child_end(NodeRef N) { return N->end(); }
- typedef llvm::pointer_iterator<df_iterator<::clang::DomTreeNode *>>
- nodes_iterator;
+ using nodes_iterator =
+ llvm::pointer_iterator<df_iterator<::clang::DomTreeNode *>>;
static nodes_iterator nodes_begin(::clang::DomTreeNode *N) {
return nodes_iterator(df_begin(getEntryNode(N)));
@@ -187,7 +183,7 @@ template <> struct GraphTraits< ::clang::DomTreeNode* > {
};
template <> struct GraphTraits< ::clang::DominatorTree* >
- : public GraphTraits< ::clang::DomTreeNode* > {
+ : public GraphTraits< ::clang::DomTreeNode* > {
static NodeRef getEntryNode(::clang::DominatorTree *DT) {
return DT->getRootNode();
}
@@ -200,6 +196,7 @@ template <> struct GraphTraits< ::clang::DominatorTree* >
return nodes_iterator(df_end(getEntryNode(N)));
}
};
-} // end namespace llvm
-#endif
+} // namespace llvm
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
index 8c531d638cc22..6f8bb9b4095fa 100644
--- a/include/clang/Analysis/Analyses/FormatString.h
+++ b/include/clang/Analysis/Analyses/FormatString.h
@@ -256,18 +256,26 @@ public:
private:
const Kind K;
QualType T;
- const char *Name;
- bool Ptr;
+ const char *Name = nullptr;
+ bool Ptr = false;
+
+ /// The TypeKind identifies certain well-known types like size_t and
+ /// ptrdiff_t.
+ enum class TypeKind { DontCare, SizeT, PtrdiffT };
+ TypeKind TK = TypeKind::DontCare;
+
public:
- ArgType(Kind k = UnknownTy, const char *n = nullptr)
- : K(k), Name(n), Ptr(false) {}
- ArgType(QualType t, const char *n = nullptr)
- : K(SpecificTy), T(t), Name(n), Ptr(false) {}
- ArgType(CanQualType t) : K(SpecificTy), T(t), Name(nullptr), Ptr(false) {}
+ ArgType(Kind K = UnknownTy, const char *N = nullptr) : K(K), Name(N) {}
+ ArgType(QualType T, const char *N = nullptr) : K(SpecificTy), T(T), Name(N) {}
+ ArgType(CanQualType T) : K(SpecificTy), T(T) {}
static ArgType Invalid() { return ArgType(InvalidTy); }
bool isValid() const { return K != InvalidTy; }
+ bool isSizeT() const { return TK == TypeKind::SizeT; }
+
+ bool isPtrdiffT() const { return TK == TypeKind::PtrdiffT; }
+
/// Create an ArgType which corresponds to the type pointer to A.
static ArgType PtrTo(const ArgType& A) {
assert(A.K >= InvalidTy && "ArgType cannot be pointer to invalid/unknown");
@@ -276,6 +284,21 @@ public:
return Res;
}
+ /// Create an ArgType which corresponds to the size_t/ssize_t type.
+ static ArgType makeSizeT(const ArgType &A) {
+ ArgType Res = A;
+ Res.TK = TypeKind::SizeT;
+ return Res;
+ }
+
+ /// Create an ArgType which corresponds to the ptrdiff_t/unsigned ptrdiff_t
+ /// type.
+ static ArgType makePtrdiffT(const ArgType &A) {
+ ArgType Res = A;
+ Res.TK = TypeKind::PtrdiffT;
+ return Res;
+ }
+
MatchKind matchesType(ASTContext &C, QualType argTy) const;
QualType getRepresentativeType(ASTContext &C) const;
@@ -510,7 +533,7 @@ public:
return getConversionSpecifier().consumesDataArgument();
}
- /// \brief Returns the builtin type that a data argument
+ /// Returns the builtin type that a data argument
/// paired with this format specifier should have. This method
/// will return null if the format specifier does not have
/// a matching data argument or the matching argument matches
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index 6a1222386bae1..21c3ba255c366 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -33,15 +33,18 @@ public:
llvm::ImmutableSet<const Stmt *> liveStmts;
llvm::ImmutableSet<const VarDecl *> liveDecls;
+ llvm::ImmutableSet<const BindingDecl *> liveBindings;
bool equals(const LivenessValues &V) const;
LivenessValues()
- : liveStmts(nullptr), liveDecls(nullptr) {}
+ : liveStmts(nullptr), liveDecls(nullptr), liveBindings(nullptr) {}
LivenessValues(llvm::ImmutableSet<const Stmt *> LiveStmts,
- llvm::ImmutableSet<const VarDecl *> LiveDecls)
- : liveStmts(LiveStmts), liveDecls(LiveDecls) {}
+ llvm::ImmutableSet<const VarDecl *> LiveDecls,
+ llvm::ImmutableSet<const BindingDecl *> LiveBindings)
+ : liveStmts(LiveStmts), liveDecls(LiveDecls),
+ liveBindings(LiveBindings) {}
bool isLive(const Stmt *S) const;
bool isLive(const VarDecl *D) const;
diff --git a/include/clang/Analysis/Analyses/PostOrderCFGView.h b/include/clang/Analysis/Analyses/PostOrderCFGView.h
index c0a93528373e2..7df3dc66c3112 100644
--- a/include/clang/Analysis/Analyses/PostOrderCFGView.h
+++ b/include/clang/Analysis/Analyses/PostOrderCFGView.h
@@ -1,4 +1,4 @@
-//===- PostOrderCFGView.h - Post order view of CFG blocks ---------*- C++ --*-//
+//===- PostOrderCFGView.h - Post order view of CFG blocks -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,22 +14,23 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_POSTORDERCFGVIEW_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_POSTORDERCFGVIEW_H
-#include <vector>
-//#include <algorithm>
-
-#include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/BitVector.h"
-
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/CFG.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include <utility>
+#include <vector>
namespace clang {
class PostOrderCFGView : public ManagedAnalysis {
virtual void anchor();
+
public:
- /// \brief Implements a set of CFGBlocks using a BitVector.
+ /// Implements a set of CFGBlocks using a BitVector.
///
/// This class contains a minimal interface, primarily dictated by the SetType
/// template parameter of the llvm::po_iterator template, as used with
@@ -37,15 +38,16 @@ public:
/// visit during the analysis.
class CFGBlockSet {
llvm::BitVector VisitedBlockIDs;
+
public:
// po_iterator requires this iterator, but the only interface needed is the
- // value_type typedef.
- struct iterator { typedef const CFGBlock *value_type; };
+ // value_type type.
+ struct iterator { using value_type = const CFGBlock *; };
- CFGBlockSet() {}
+ CFGBlockSet() = default;
CFGBlockSet(const CFG *G) : VisitedBlockIDs(G->getNumBlockIDs(), false) {}
- /// \brief Set the bit associated with a particular CFGBlock.
+ /// Set the bit associated with a particular CFGBlock.
/// This is the important method for the SetType template parameter.
std::pair<llvm::NoneType, bool> insert(const CFGBlock *Block) {
// Note that insert() is called by po_iterator, which doesn't check to
@@ -60,7 +62,7 @@ public:
return std::make_pair(None, true);
}
- /// \brief Check if the bit for a CFGBlock has been already set.
+ /// Check if the bit for a CFGBlock has been already set.
/// This method is for tracking visited blocks in the main threadsafety
/// loop. Block must not be null.
bool alreadySet(const CFGBlock *Block) {
@@ -69,33 +71,34 @@ public:
};
private:
- typedef llvm::po_iterator<const CFG*, CFGBlockSet, true> po_iterator;
- std::vector<const CFGBlock*> Blocks;
+ using po_iterator = llvm::po_iterator<const CFG *, CFGBlockSet, true>;
+ std::vector<const CFGBlock *> Blocks;
- typedef llvm::DenseMap<const CFGBlock *, unsigned> BlockOrderTy;
+ using BlockOrderTy = llvm::DenseMap<const CFGBlock *, unsigned>;
BlockOrderTy BlockOrder;
public:
- typedef std::vector<const CFGBlock *>::reverse_iterator iterator;
- typedef std::vector<const CFGBlock *>::const_reverse_iterator const_iterator;
+ friend struct BlockOrderCompare;
+
+ using iterator = std::vector<const CFGBlock *>::reverse_iterator;
+ using const_iterator = std::vector<const CFGBlock *>::const_reverse_iterator;
PostOrderCFGView(const CFG *cfg);
iterator begin() { return Blocks.rbegin(); }
- iterator end() { return Blocks.rend(); }
+ iterator end() { return Blocks.rend(); }
const_iterator begin() const { return Blocks.rbegin(); }
const_iterator end() const { return Blocks.rend(); }
bool empty() const { return begin() == end(); }
- struct BlockOrderCompare;
- friend struct BlockOrderCompare;
-
struct BlockOrderCompare {
const PostOrderCFGView &POV;
+
public:
BlockOrderCompare(const PostOrderCFGView &pov) : POV(pov) {}
+
bool operator()(const CFGBlock *b1, const CFGBlock *b2) const;
};
@@ -109,7 +112,6 @@ public:
static PostOrderCFGView *create(AnalysisDeclContext &analysisContext);
};
-} // end clang namespace
-
-#endif
+} // namespace clang
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_POSTORDERCFGVIEW_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h
index 7e403b1f40906..c72db6f2b24bb 100644
--- a/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -1,4 +1,4 @@
-//===- ThreadSafety.h ------------------------------------------*- C++ --*-===//
+//===- ThreadSafety.h -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,11 +19,15 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
-#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/StringRef.h"
namespace clang {
+
+class AnalysisDeclContext;
+class FunctionDecl;
+class NamedDecl;
+
namespace threadSafety {
class BeforeSet;
@@ -31,27 +35,44 @@ class BeforeSet;
/// This enum distinguishes between different kinds of operations that may
/// need to be protected by locks. We use this enum in error handling.
enum ProtectedOperationKind {
- POK_VarDereference, ///< Dereferencing a variable (e.g. p in *p = 5;)
- POK_VarAccess, ///< Reading or writing a variable (e.g. x in x = 5;)
- POK_FunctionCall, ///< Making a function call (e.g. fool())
- POK_PassByRef, ///< Passing a guarded variable by reference.
- POK_PtPassByRef, ///< Passing a pt-guarded variable by reference.
+ /// Dereferencing a variable (e.g. p in *p = 5;)
+ POK_VarDereference,
+
+ /// Reading or writing a variable (e.g. x in x = 5;)
+ POK_VarAccess,
+
+ /// Making a function call (e.g. fool())
+ POK_FunctionCall,
+
+ /// Passing a guarded variable by reference.
+ POK_PassByRef,
+
+ /// Passing a pt-guarded variable by reference.
+ POK_PtPassByRef
};
/// This enum distinguishes between different kinds of lock actions. For
/// example, it is an error to write a variable protected by shared version of a
/// mutex.
enum LockKind {
- LK_Shared, ///< Shared/reader lock of a mutex.
- LK_Exclusive, ///< Exclusive/writer lock of a mutex.
- LK_Generic ///< Can be either Shared or Exclusive
+ /// Shared/reader lock of a mutex.
+ LK_Shared,
+
+ /// Exclusive/writer lock of a mutex.
+ LK_Exclusive,
+
+ /// Can be either Shared or Exclusive.
+ LK_Generic
};
/// This enum distinguishes between different ways to access (read or write) a
/// variable.
enum AccessKind {
- AK_Read, ///< Reading a variable.
- AK_Written ///< Writing a variable.
+ /// Reading a variable.
+ AK_Read,
+
+ /// Writing a variable.
+ AK_Written
};
/// This enum distinguishes between different situations where we warn due to
@@ -72,8 +93,9 @@ enum LockErrorKind {
/// Handler class for thread safety warnings.
class ThreadSafetyHandler {
public:
- typedef StringRef Name;
- ThreadSafetyHandler() : IssueBetaWarnings(false) { }
+ using Name = StringRef;
+
+ ThreadSafetyHandler() = default;
virtual ~ThreadSafetyHandler();
/// Warn about lock expressions which fail to resolve to lockable objects.
@@ -185,7 +207,6 @@ public:
virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
Name LockName, SourceLocation Loc) {}
-
/// Warn that L1 cannot be acquired before L2.
virtual void handleLockAcquiredBefore(StringRef Kind, Name L1Name,
Name L2Name, SourceLocation Loc) {}
@@ -204,10 +225,10 @@ public:
void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; }
private:
- bool IssueBetaWarnings;
+ bool IssueBetaWarnings = false;
};
-/// \brief Check a function's CFG for thread-safety violations.
+/// Check a function's CFG for thread-safety violations.
///
/// We traverse the blocks in the CFG, compute the set of mutexes that are held
/// at the end of each block, and issue warnings for thread safety violations.
@@ -218,9 +239,11 @@ void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
void threadSafetyCleanup(BeforeSet *Cache);
-/// \brief Helper function that returns a LockKind required for the given level
+/// Helper function that returns a LockKind required for the given level
/// of access.
LockKind getLockKindFromAccessKind(AccessKind AK);
-}} // end namespace clang::threadSafety
-#endif
+} // namespace threadSafety
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
index 414645b7231bd..580872e17ef46 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
@@ -1,4 +1,4 @@
-//===- ThreadSafetyCommon.h ------------------------------------*- C++ --*-===//
+//===- ThreadSafetyCommon.h -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -22,20 +22,41 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
+#include "clang/AST/Decl.h"
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
+#include "clang/Analysis/Analyses/ThreadSafetyUtil.h"
#include "clang/Analysis/AnalysisDeclContext.h"
-#include "clang/Basic/OperatorKinds.h"
-#include <memory>
-#include <ostream>
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
#include <sstream>
+#include <string>
+#include <utility>
#include <vector>
-
namespace clang {
-namespace threadSafety {
+class AbstractConditionalOperator;
+class ArraySubscriptExpr;
+class BinaryOperator;
+class CallExpr;
+class CastExpr;
+class CXXDestructorDecl;
+class CXXMemberCallExpr;
+class CXXOperatorCallExpr;
+class CXXThisExpr;
+class DeclRefExpr;
+class DeclStmt;
+class Expr;
+class MemberExpr;
+class Stmt;
+class UnaryOperator;
+
+namespace threadSafety {
// Various helper functions on til::SExpr
namespace sx {
@@ -72,9 +93,7 @@ inline std::string toString(const til::SExpr *E) {
return ss.str();
}
-} // end namespace sx
-
-
+} // namespace sx
// This class defines the interface of a clang CFG Visitor.
// CFGWalker will invoke the following methods.
@@ -123,11 +142,10 @@ class CFGVisitor {
void exitCFG(const CFGBlock *Last) {}
};
-
// Walks the clang CFG, and invokes methods on a given CFGVisitor.
class CFGWalker {
public:
- CFGWalker() : CFGraph(nullptr), ACtx(nullptr), SortedGraph(nullptr) {}
+ CFGWalker() = default;
// Initialize the CFGWalker. This setup only needs to be done once, even
// if there are multiple passes over the CFG.
@@ -186,15 +204,15 @@ public:
// Process statements
for (const auto &BI : *CurrBlock) {
switch (BI.getKind()) {
- case CFGElement::Statement: {
+ case CFGElement::Statement:
V.handleStatement(BI.castAs<CFGStmt>().getStmt());
break;
- }
+
case CFGElement::AutomaticObjectDtor: {
CFGAutomaticObjDtor AD = BI.castAs<CFGAutomaticObjDtor>();
- CXXDestructorDecl *DD = const_cast<CXXDestructorDecl*>(
+ auto *DD = const_cast<CXXDestructorDecl *>(
AD.getDestructorDecl(ACtx->getASTContext()));
- VarDecl *VD = const_cast<VarDecl*>(AD.getVarDecl());
+ auto *VD = const_cast<VarDecl *>(AD.getVarDecl());
V.handleDestructorCall(VD, DD);
break;
}
@@ -242,28 +260,27 @@ public:
const PostOrderCFGView *getSortedGraph() const { return SortedGraph; }
private:
- CFG *CFGraph;
- AnalysisDeclContext *ACtx;
- PostOrderCFGView *SortedGraph;
+ CFG *CFGraph = nullptr;
+ AnalysisDeclContext *ACtx = nullptr;
+ PostOrderCFGView *SortedGraph = nullptr;
};
-
-
-
+// TODO: move this back into ThreadSafety.cpp
+// This is specific to thread safety. It is here because
+// translateAttrExpr needs it, but that should be moved too.
class CapabilityExpr {
- // TODO: move this back into ThreadSafety.cpp
- // This is specific to thread safety. It is here because
- // translateAttrExpr needs it, but that should be moved too.
-
private:
- const til::SExpr* CapExpr; ///< The capability expression.
- bool Negated; ///< True if this is a negative capability
+ /// The capability expression.
+ const til::SExpr* CapExpr;
+
+ /// True if this is a negative capability.
+ bool Negated;
public:
CapabilityExpr(const til::SExpr *E, bool Neg) : CapExpr(E), Negated(Neg) {}
- const til::SExpr* sexpr() const { return CapExpr; }
- bool negative() const { return Negated; }
+ const til::SExpr* sexpr() const { return CapExpr; }
+ bool negative() const { return Negated; }
CapabilityExpr operator!() const {
return CapabilityExpr(CapExpr, !Negated);
@@ -289,9 +306,9 @@ public:
const ValueDecl* valueDecl() const {
if (Negated || CapExpr == nullptr)
return nullptr;
- if (auto *P = dyn_cast<til::Project>(CapExpr))
+ if (const auto *P = dyn_cast<til::Project>(CapExpr))
return P->clangDecl();
- if (auto *P = dyn_cast<til::LiteralPtr>(CapExpr))
+ if (const auto *P = dyn_cast<til::LiteralPtr>(CapExpr))
return P->clangDecl();
return nullptr;
}
@@ -309,12 +326,10 @@ public:
bool isUniversal() const { return sexpr() && isa<til::Wildcard>(sexpr()); }
};
-
-
// Translate clang::Expr to til::SExpr.
class SExprBuilder {
public:
- /// \brief Encapsulates the lexical context of a function call. The lexical
+ /// Encapsulates the lexical context of a function call. The lexical
/// context includes the arguments to the call, including the implicit object
/// argument. When an attribute containing a mutex expression is attached to
/// a method, the expression may refer to formal parameters of the method.
@@ -324,22 +339,29 @@ public:
/// should be evaluated; multiple calling contexts can be chained together
/// by the lock_returned attribute.
struct CallingContext {
- CallingContext *Prev; // The previous context; or 0 if none.
- const NamedDecl *AttrDecl; // The decl to which the attr is attached.
- const Expr *SelfArg; // Implicit object argument -- e.g. 'this'
- unsigned NumArgs; // Number of funArgs
- const Expr *const *FunArgs; // Function arguments
- bool SelfArrow; // is Self referred to with -> or .?
+ // The previous context; or 0 if none.
+ CallingContext *Prev;
+
+ // The decl to which the attr is attached.
+ const NamedDecl *AttrDecl;
+
+ // Implicit object argument -- e.g. 'this'
+ const Expr *SelfArg = nullptr;
+
+ // Number of funArgs
+ unsigned NumArgs = 0;
+
+ // Function arguments
+ const Expr *const *FunArgs = nullptr;
+
+ // is Self referred to with -> or .?
+ bool SelfArrow = false;
CallingContext(CallingContext *P, const NamedDecl *D = nullptr)
- : Prev(P), AttrDecl(D), SelfArg(nullptr),
- NumArgs(0), FunArgs(nullptr), SelfArrow(false)
- {}
+ : Prev(P), AttrDecl(D) {}
};
- SExprBuilder(til::MemRegionRef A)
- : Arena(A), SelfVar(nullptr), Scfg(nullptr), CurrentBB(nullptr),
- CurrentBlockInfo(nullptr) {
+ SExprBuilder(til::MemRegionRef A) : Arena(A) {
// FIXME: we don't always have a self-variable.
SelfVar = new (Arena) til::Variable(nullptr);
SelfVar->setKind(til::Variable::VK_SFun);
@@ -368,6 +390,9 @@ public:
til::SCFG *getCFG() { return Scfg; }
private:
+ // We implement the CFGVisitor API
+ friend class CFGWalker;
+
til::SExpr *translateDeclRefExpr(const DeclRefExpr *DRE,
CallingContext *Ctx) ;
til::SExpr *translateCXXThisExpr(const CXXThisExpr *TE, CallingContext *Ctx);
@@ -397,31 +422,30 @@ private:
til::SExpr *translateDeclStmt(const DeclStmt *S, CallingContext *Ctx);
// Map from statements in the clang CFG to SExprs in the til::SCFG.
- typedef llvm::DenseMap<const Stmt*, til::SExpr*> StatementMap;
+ using StatementMap = llvm::DenseMap<const Stmt *, til::SExpr *>;
// Map from clang local variables to indices in a LVarDefinitionMap.
- typedef llvm::DenseMap<const ValueDecl *, unsigned> LVarIndexMap;
+ using LVarIndexMap = llvm::DenseMap<const ValueDecl *, unsigned>;
// Map from local variable indices to SSA variables (or constants).
- typedef std::pair<const ValueDecl *, til::SExpr *> NameVarPair;
- typedef CopyOnWriteVector<NameVarPair> LVarDefinitionMap;
+ using NameVarPair = std::pair<const ValueDecl *, til::SExpr *>;
+ using LVarDefinitionMap = CopyOnWriteVector<NameVarPair>;
struct BlockInfo {
LVarDefinitionMap ExitMap;
- bool HasBackEdges;
- unsigned UnprocessedSuccessors; // Successors yet to be processed
- unsigned ProcessedPredecessors; // Predecessors already processed
+ bool HasBackEdges = false;
- BlockInfo()
- : HasBackEdges(false), UnprocessedSuccessors(0),
- ProcessedPredecessors(0) {}
+ // Successors yet to be processed
+ unsigned UnprocessedSuccessors = 0;
+
+ // Predecessors already processed
+ unsigned ProcessedPredecessors = 0;
+
+ BlockInfo() = default;
BlockInfo(BlockInfo &&) = default;
BlockInfo &operator=(BlockInfo &&) = default;
};
- // We implement the CFGVisitor API
- friend class CFGWalker;
-
void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First);
void enterCFGBlock(const CFGBlock *B);
bool visitPredecessors() { return true; }
@@ -440,6 +464,7 @@ private:
void insertStmt(const Stmt *S, til::SExpr *E) {
SMap.insert(std::make_pair(S, E));
}
+
til::SExpr *getCurrentLVarDefinition(const ValueDecl *VD);
til::SExpr *addStatement(til::SExpr *E, const Stmt *S,
@@ -459,30 +484,36 @@ private:
static const bool CapabilityExprMode = true;
til::MemRegionRef Arena;
- til::Variable *SelfVar; // Variable to use for 'this'. May be null.
- til::SCFG *Scfg;
- StatementMap SMap; // Map from Stmt to TIL Variables
- LVarIndexMap LVarIdxMap; // Indices of clang local vars.
- std::vector<til::BasicBlock *> BlockMap; // Map from clang to til BBs.
- std::vector<BlockInfo> BBInfo; // Extra information per BB.
- // Indexed by clang BlockID.
+ // Variable to use for 'this'. May be null.
+ til::Variable *SelfVar = nullptr;
+
+ til::SCFG *Scfg = nullptr;
+
+ // Map from Stmt to TIL Variables
+ StatementMap SMap;
+
+ // Indices of clang local vars.
+ LVarIndexMap LVarIdxMap;
+
+ // Map from clang to til BBs.
+ std::vector<til::BasicBlock *> BlockMap;
+
+ // Extra information per BB. Indexed by clang BlockID.
+ std::vector<BlockInfo> BBInfo;
LVarDefinitionMap CurrentLVarMap;
- std::vector<til::Phi*> CurrentArguments;
- std::vector<til::SExpr*> CurrentInstructions;
- std::vector<til::Phi*> IncompleteArgs;
- til::BasicBlock *CurrentBB;
- BlockInfo *CurrentBlockInfo;
+ std::vector<til::Phi *> CurrentArguments;
+ std::vector<til::SExpr *> CurrentInstructions;
+ std::vector<til::Phi *> IncompleteArgs;
+ til::BasicBlock *CurrentBB = nullptr;
+ BlockInfo *CurrentBlockInfo = nullptr;
};
-
// Dump an SCFG to llvm::errs().
void printSCFG(CFGWalker &Walker);
+} // namespace threadSafety
+} // namespace clang
-} // end namespace threadSafety
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_THREAD_SAFETY_COMMON_H
+#endif // LLVM_CLANG_THREAD_SAFETY_COMMON_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
index bc78021343a45..2508af1af1079 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
@@ -29,7 +29,7 @@ public:
};
Opcode kind() const { return Kind; }
- /// \brief Logical implication. Returns true if the LExpr implies RHS, i.e. if
+ /// Logical implication. Returns true if the LExpr implies RHS, i.e. if
/// the LExpr holds, then RHS must hold. For example, (A & B) implies A.
inline bool implies(const LExpr *RHS) const;
@@ -92,7 +92,7 @@ public:
static bool classof(const LExpr *E) { return E->kind() == LExpr::Not; }
};
-/// \brief Logical implication. Returns true if LHS implies RHS, i.e. if LHS
+/// Logical implication. Returns true if LHS implies RHS, i.e. if LHS
/// holds, then RHS must hold. For example, (A & B) implies A.
bool implies(const LExpr *LHS, const LExpr *RHS);
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
index 0a58d2a80250a..810f2052b7a5c 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
@@ -1,4 +1,4 @@
-//===- ThreadSafetyTIL.h ---------------------------------------*- C++ --*-===//
+//===- ThreadSafetyTIL.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -47,20 +47,33 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTIL_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTIL_H
-// All clang include dependencies for this file must be put in
-// ThreadSafetyUtil.h.
-#include "ThreadSafetyUtil.h"
+#include "clang/AST/Decl.h"
+#include "clang/Analysis/Analyses/ThreadSafetyUtil.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
-#include <stdint.h>
+#include <cstdint>
+#include <iterator>
+#include <string>
#include <utility>
-
namespace clang {
+
+class CallExpr;
+class Expr;
+class Stmt;
+
namespace threadSafety {
namespace til {
+class BasicBlock;
/// Enum for the different distinct classes of SExpr
enum TIL_Opcode {
@@ -100,11 +113,21 @@ enum TIL_BinaryOpcode : unsigned char {
/// Opcode for cast operations.
enum TIL_CastOpcode : unsigned char {
CAST_none = 0,
- CAST_extendNum, // extend precision of numeric type
- CAST_truncNum, // truncate precision of numeric type
- CAST_toFloat, // convert to floating point type
- CAST_toInt, // convert to integer type
- CAST_objToPtr // convert smart pointer to pointer (C++ only)
+
+ // Extend precision of numeric type
+ CAST_extendNum,
+
+ // Truncate precision of numeric type
+ CAST_truncNum,
+
+ // Convert to floating point type
+ CAST_toFloat,
+
+ // Convert to integer type
+ CAST_toInt,
+
+ // Convert smart pointer to pointer (C++ only)
+ CAST_objToPtr
};
const TIL_Opcode COP_Min = COP_Future;
@@ -122,7 +145,6 @@ StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op);
/// Return the name of a binary opcode.
StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op);
-
/// ValueTypes are data types that can actually be held in registers.
/// All variables and expressions must have a value type.
/// Pointer types are further subdivided into the various heap-allocated
@@ -150,22 +172,22 @@ struct ValueType {
ST_128
};
+ ValueType(BaseType B, SizeType Sz, bool S, unsigned char VS)
+ : Base(B), Size(Sz), Signed(S), VectSize(VS) {}
+
inline static SizeType getSizeType(unsigned nbytes);
template <class T>
inline static ValueType getValueType();
- ValueType(BaseType B, SizeType Sz, bool S, unsigned char VS)
- : Base(B), Size(Sz), Signed(S), VectSize(VS)
- { }
+ BaseType Base;
+ SizeType Size;
+ bool Signed;
- BaseType Base;
- SizeType Size;
- bool Signed;
- unsigned char VectSize; // 0 for scalar, otherwise num elements in vector
+ // 0 for scalar, otherwise num elements in vector
+ unsigned char VectSize;
};
-
inline ValueType::SizeType ValueType::getSizeType(unsigned nbytes) {
switch (nbytes) {
case 1: return ST_8;
@@ -177,7 +199,6 @@ inline ValueType::SizeType ValueType::getSizeType(unsigned nbytes) {
}
}
-
template<>
inline ValueType ValueType::getValueType<void>() {
return ValueType(BT_Void, ST_0, false, 0);
@@ -253,13 +274,11 @@ inline ValueType ValueType::getValueType<void*>() {
return ValueType(BT_Pointer, getSizeType(sizeof(void*)), false, 0);
}
-
-class BasicBlock;
-
-
/// Base class for AST nodes in the typed intermediate language.
class SExpr {
public:
+ SExpr() = delete;
+
TIL_Opcode opcode() const { return static_cast<TIL_Opcode>(Opcode); }
// Subclasses of SExpr must define the following:
@@ -280,6 +299,9 @@ public:
return ::operator new(S, R);
}
+ /// SExpr objects must be created in an arena.
+ void *operator new(size_t) = delete;
+
/// SExpr objects cannot be deleted.
// This declaration is public to workaround a gcc bug that breaks building
// with REQUIRES_EH=1.
@@ -291,45 +313,33 @@ public:
/// Returns the block, if this is an instruction in a basic block,
/// otherwise returns null.
- BasicBlock* block() const { return Block; }
+ BasicBlock *block() const { return Block; }
/// Set the basic block and instruction ID for this expression.
void setID(BasicBlock *B, unsigned id) { Block = B; SExprID = id; }
protected:
- SExpr(TIL_Opcode Op)
- : Opcode(Op), Reserved(0), Flags(0), SExprID(0), Block(nullptr) {}
- SExpr(const SExpr &E)
- : Opcode(E.Opcode), Reserved(0), Flags(E.Flags), SExprID(0),
- Block(nullptr) {}
+ SExpr(TIL_Opcode Op) : Opcode(Op) {}
+ SExpr(const SExpr &E) : Opcode(E.Opcode), Flags(E.Flags) {}
const unsigned char Opcode;
- unsigned char Reserved;
- unsigned short Flags;
- unsigned SExprID;
- BasicBlock* Block;
-
-private:
- SExpr() = delete;
-
- /// SExpr objects must be created in an arena.
- void *operator new(size_t) = delete;
+ unsigned char Reserved = 0;
+ unsigned short Flags = 0;
+ unsigned SExprID = 0;
+ BasicBlock *Block = nullptr;
};
-
// Contains various helper functions for SExprs.
namespace ThreadSafetyTIL {
- inline bool isTrivial(const SExpr *E) {
- unsigned Op = E->opcode();
- return Op == COP_Variable || Op == COP_Literal || Op == COP_LiteralPtr;
- }
+
+inline bool isTrivial(const SExpr *E) {
+ unsigned Op = E->opcode();
+ return Op == COP_Variable || Op == COP_Literal || Op == COP_LiteralPtr;
}
-// Nodes which declare variables
-class Function;
-class SFunction;
-class Let;
+} // namespace ThreadSafetyTIL
+// Nodes which declare variables
/// A named variable, e.g. "x".
///
@@ -345,28 +355,35 @@ class Let;
/// pointer to the original declaration.
class Variable : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Variable; }
-
enum VariableKind {
- VK_Let, ///< Let-variable
- VK_Fun, ///< Function parameter
- VK_SFun ///< SFunction (self) parameter
+ /// Let-variable
+ VK_Let,
+
+ /// Function parameter
+ VK_Fun,
+
+ /// SFunction (self) parameter
+ VK_SFun
};
Variable(StringRef s, SExpr *D = nullptr)
- : SExpr(COP_Variable), Name(s), Definition(D), Cvdecl(nullptr) {
+ : SExpr(COP_Variable), Name(s), Definition(D) {
Flags = VK_Let;
}
- Variable(SExpr *D, const clang::ValueDecl *Cvd = nullptr)
+
+ Variable(SExpr *D, const ValueDecl *Cvd = nullptr)
: SExpr(COP_Variable), Name(Cvd ? Cvd->getName() : "_x"),
Definition(D), Cvdecl(Cvd) {
Flags = VK_Let;
}
+
Variable(const Variable &Vd, SExpr *D) // rewrite constructor
: SExpr(Vd), Name(Vd.Name), Definition(D), Cvdecl(Vd.Cvdecl) {
Flags = Vd.kind();
}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Variable; }
+
/// Return the kind of variable (let, function param, or self)
VariableKind kind() const { return static_cast<VariableKind>(Flags); }
@@ -374,7 +391,7 @@ public:
StringRef name() const { return Name; }
/// Return the clang declaration for this variable, if any.
- const clang::ValueDecl *clangDecl() const { return Cvdecl; }
+ const ValueDecl *clangDecl() const { return Cvdecl; }
/// Return the definition of the variable.
/// For let-vars, this is the setting expression.
@@ -385,7 +402,7 @@ public:
void setName(StringRef S) { Name = S; }
void setKind(VariableKind K) { Flags = K; }
void setDefinition(SExpr *E) { Definition = E; }
- void setClangDecl(const clang::ValueDecl *VD) { Cvdecl = VD; }
+ void setClangDecl(const ValueDecl *VD) { Cvdecl = VD; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -399,42 +416,41 @@ public:
}
private:
- friend class Function;
- friend class SFunction;
friend class BasicBlock;
+ friend class Function;
friend class Let;
+ friend class SFunction;
- StringRef Name; // The name of the variable.
- SExpr* Definition; // The TIL type or definition
- const clang::ValueDecl *Cvdecl; // The clang declaration for this variable.
-};
+ // The name of the variable.
+ StringRef Name;
+
+ // The TIL type or definition.
+ SExpr *Definition;
+ // The clang declaration for this variable.
+ const ValueDecl *Cvdecl = nullptr;
+};
/// Placeholder for an expression that has not yet been created.
/// Used to implement lazy copy and rewriting strategies.
class Future : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Future; }
-
enum FutureStatus {
FS_pending,
FS_evaluating,
FS_done
};
- Future() : SExpr(COP_Future), Status(FS_pending), Result(nullptr) {}
-
-private:
+ Future() : SExpr(COP_Future) {}
virtual ~Future() = delete;
-public:
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Future; }
+
// A lazy rewriting strategy should subclass Future and override this method.
virtual SExpr *compute() { return nullptr; }
// Return the result of this future if it exists, otherwise return null.
- SExpr *maybeGetResult() const {
- return Result;
- }
+ SExpr *maybeGetResult() const { return Result; }
// Return the result of this future; forcing it if necessary.
SExpr *result() {
@@ -464,19 +480,18 @@ public:
private:
SExpr* force();
- FutureStatus Status;
- SExpr *Result;
+ FutureStatus Status = FS_pending;
+ SExpr *Result = nullptr;
};
-
/// Placeholder for expressions that cannot be represented in the TIL.
class Undefined : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Undefined; }
-
- Undefined(const clang::Stmt *S = nullptr) : SExpr(COP_Undefined), Cstmt(S) {}
+ Undefined(const Stmt *S = nullptr) : SExpr(COP_Undefined), Cstmt(S) {}
Undefined(const Undefined &U) : SExpr(U), Cstmt(U.Cstmt) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Undefined; }
+
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
return Vs.reduceUndefined(*this);
@@ -488,17 +503,16 @@ public:
}
private:
- const clang::Stmt *Cstmt;
+ const Stmt *Cstmt;
};
-
/// Placeholder for a wildcard that matches any other expression.
class Wildcard : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Wildcard; }
-
Wildcard() : SExpr(COP_Wildcard) {}
- Wildcard(const Wildcard &W) : SExpr(W) {}
+ Wildcard(const Wildcard &) = default;
+
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Wildcard; }
template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
return Vs.reduceWildcard(*this);
@@ -510,22 +524,20 @@ public:
}
};
-
template <class T> class LiteralT;
// Base class for literal values.
class Literal : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Literal; }
+ Literal(const Expr *C)
+ : SExpr(COP_Literal), ValType(ValueType::getValueType<void>()), Cexpr(C) {}
+ Literal(ValueType VT) : SExpr(COP_Literal), ValType(VT) {}
+ Literal(const Literal &) = default;
- Literal(const clang::Expr *C)
- : SExpr(COP_Literal), ValType(ValueType::getValueType<void>()), Cexpr(C)
- { }
- Literal(ValueType VT) : SExpr(COP_Literal), ValType(VT), Cexpr(nullptr) {}
- Literal(const Literal &L) : SExpr(L), ValType(L.ValType), Cexpr(L.Cexpr) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Literal; }
// The clang expression for this literal.
- const clang::Expr *clangExpr() const { return Cexpr; }
+ const Expr *clangExpr() const { return Cexpr; }
ValueType valueType() const { return ValType; }
@@ -546,26 +558,23 @@ public:
private:
const ValueType ValType;
- const clang::Expr *Cexpr;
+ const Expr *Cexpr = nullptr;
};
-
// Derived class for literal values, which stores the actual value.
template<class T>
class LiteralT : public Literal {
public:
- LiteralT(T Dat) : Literal(ValueType::getValueType<T>()), Val(Dat) { }
- LiteralT(const LiteralT<T> &L) : Literal(L), Val(L.Val) { }
+ LiteralT(T Dat) : Literal(ValueType::getValueType<T>()), Val(Dat) {}
+ LiteralT(const LiteralT<T> &L) : Literal(L), Val(L.Val) {}
- T value() const { return Val;}
+ T value() const { return Val;}
T& value() { return Val; }
private:
T Val;
};
-
-
template <class V>
typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) {
if (Cexpr)
@@ -622,18 +631,17 @@ typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) {
return Vs.reduceLiteral(*this);
}
-
/// A Literal pointer to an object allocated in memory.
/// At compile time, pointer literals are represented by symbolic names.
class LiteralPtr : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_LiteralPtr; }
+ LiteralPtr(const ValueDecl *D) : SExpr(COP_LiteralPtr), Cvdecl(D) {}
+ LiteralPtr(const LiteralPtr &) = default;
- LiteralPtr(const clang::ValueDecl *D) : SExpr(COP_LiteralPtr), Cvdecl(D) {}
- LiteralPtr(const LiteralPtr &R) : SExpr(R), Cvdecl(R.Cvdecl) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_LiteralPtr; }
// The clang declaration for the value that this pointer points to.
- const clang::ValueDecl *clangDecl() const { return Cvdecl; }
+ const ValueDecl *clangDecl() const { return Cvdecl; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -646,26 +654,26 @@ public:
}
private:
- const clang::ValueDecl *Cvdecl;
+ const ValueDecl *Cvdecl;
};
-
/// A function -- a.k.a. lambda abstraction.
/// Functions with multiple arguments are created by currying,
/// e.g. (Function (x: Int) (Function (y: Int) (Code { return x + y })))
class Function : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Function; }
-
Function(Variable *Vd, SExpr *Bd)
: SExpr(COP_Function), VarDecl(Vd), Body(Bd) {
Vd->setKind(Variable::VK_Fun);
}
+
Function(const Function &F, Variable *Vd, SExpr *Bd) // rewrite constructor
: SExpr(F), VarDecl(Vd), Body(Bd) {
Vd->setKind(Variable::VK_Fun);
}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Function; }
+
Variable *variableDecl() { return VarDecl; }
const Variable *variableDecl() const { return VarDecl; }
@@ -700,20 +708,18 @@ private:
SExpr* Body;
};
-
/// A self-applicable function.
/// A self-applicable function can be applied to itself. It's useful for
/// implementing objects and late binding.
class SFunction : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_SFunction; }
-
SFunction(Variable *Vd, SExpr *B)
: SExpr(COP_SFunction), VarDecl(Vd), Body(B) {
assert(Vd->Definition == nullptr);
Vd->setKind(Variable::VK_SFun);
Vd->Definition = this;
}
+
SFunction(const SFunction &F, Variable *Vd, SExpr *B) // rewrite constructor
: SExpr(F), VarDecl(Vd), Body(B) {
assert(Vd->Definition == nullptr);
@@ -721,6 +727,8 @@ public:
Vd->Definition = this;
}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_SFunction; }
+
Variable *variableDecl() { return VarDecl; }
const Variable *variableDecl() const { return VarDecl; }
@@ -752,16 +760,15 @@ private:
SExpr* Body;
};
-
/// A block of code -- e.g. the body of a function.
class Code : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Code; }
-
Code(SExpr *T, SExpr *B) : SExpr(COP_Code), ReturnType(T), Body(B) {}
Code(const Code &C, SExpr *T, SExpr *B) // rewrite constructor
: SExpr(C), ReturnType(T), Body(B) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Code; }
+
SExpr *returnType() { return ReturnType; }
const SExpr *returnType() const { return ReturnType; }
@@ -788,16 +795,15 @@ private:
SExpr* Body;
};
-
/// A typed, writable location in memory
class Field : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Field; }
-
Field(SExpr *R, SExpr *B) : SExpr(COP_Field), Range(R), Body(B) {}
Field(const Field &C, SExpr *R, SExpr *B) // rewrite constructor
: SExpr(C), Range(R), Body(B) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Field; }
+
SExpr *range() { return Range; }
const SExpr *range() const { return Range; }
@@ -824,7 +830,6 @@ private:
SExpr* Body;
};
-
/// Apply an argument to a function.
/// Note that this does not actually call the function. Functions are curried,
/// so this returns a closure in which the first parameter has been applied.
@@ -832,12 +837,11 @@ private:
/// function.
class Apply : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Apply; }
-
Apply(SExpr *F, SExpr *A) : SExpr(COP_Apply), Fun(F), Arg(A) {}
Apply(const Apply &A, SExpr *F, SExpr *Ar) // rewrite constructor
- : SExpr(A), Fun(F), Arg(Ar)
- {}
+ : SExpr(A), Fun(F), Arg(Ar) {}
+
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Apply; }
SExpr *fun() { return Fun; }
const SExpr *fun() const { return Fun; }
@@ -865,16 +869,15 @@ private:
SExpr* Arg;
};
-
/// Apply a self-argument to a self-applicable function.
class SApply : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_SApply; }
-
SApply(SExpr *Sf, SExpr *A = nullptr) : SExpr(COP_SApply), Sfun(Sf), Arg(A) {}
SApply(SApply &A, SExpr *Sf, SExpr *Ar = nullptr) // rewrite constructor
: SExpr(A), Sfun(Sf), Arg(Ar) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_SApply; }
+
SExpr *sfun() { return Sfun; }
const SExpr *sfun() const { return Sfun; }
@@ -904,23 +907,23 @@ private:
SExpr* Arg;
};
-
/// Project a named slot from a C++ struct or class.
class Project : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Project; }
-
- Project(SExpr *R, const clang::ValueDecl *Cvd)
+ Project(SExpr *R, const ValueDecl *Cvd)
: SExpr(COP_Project), Rec(R), Cvdecl(Cvd) {
assert(Cvd && "ValueDecl must not be null");
}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Project; }
+
SExpr *record() { return Rec; }
const SExpr *record() const { return Rec; }
- const clang::ValueDecl *clangDecl() const { return Cvdecl; }
+ const ValueDecl *clangDecl() const { return Cvdecl; }
bool isArrow() const { return (Flags & 0x01) != 0; }
+
void setArrow(bool b) {
if (b) Flags |= 0x01;
else Flags &= 0xFFFE;
@@ -954,23 +957,22 @@ public:
private:
SExpr* Rec;
mutable llvm::Optional<std::string> SlotName;
- const clang::ValueDecl *Cvdecl;
+ const ValueDecl *Cvdecl;
};
-
/// Call a function (after all arguments have been applied).
class Call : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
-
- Call(SExpr *T, const clang::CallExpr *Ce = nullptr)
+ Call(SExpr *T, const CallExpr *Ce = nullptr)
: SExpr(COP_Call), Target(T), Cexpr(Ce) {}
Call(const Call &C, SExpr *T) : SExpr(C), Target(T), Cexpr(C.Cexpr) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
+
SExpr *target() { return Target; }
const SExpr *target() const { return Target; }
- const clang::CallExpr *clangCallExpr() const { return Cexpr; }
+ const CallExpr *clangCallExpr() const { return Cexpr; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -985,15 +987,12 @@ public:
private:
SExpr* Target;
- const clang::CallExpr *Cexpr;
+ const CallExpr *Cexpr;
};
-
/// Allocate memory for a new value on the heap or stack.
class Alloc : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
-
enum AllocKind {
AK_Stack,
AK_Heap
@@ -1002,6 +1001,8 @@ public:
Alloc(SExpr *D, AllocKind K) : SExpr(COP_Alloc), Dtype(D) { Flags = K; }
Alloc(const Alloc &A, SExpr *Dt) : SExpr(A), Dtype(Dt) { Flags = A.kind(); }
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
+
AllocKind kind() const { return static_cast<AllocKind>(Flags); }
SExpr *dataType() { return Dtype; }
@@ -1025,15 +1026,14 @@ private:
SExpr* Dtype;
};
-
/// Load a value from memory.
class Load : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Load; }
-
Load(SExpr *P) : SExpr(COP_Load), Ptr(P) {}
Load(const Load &L, SExpr *P) : SExpr(L), Ptr(P) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Load; }
+
SExpr *pointer() { return Ptr; }
const SExpr *pointer() const { return Ptr; }
@@ -1052,16 +1052,15 @@ private:
SExpr* Ptr;
};
-
/// Store a value to memory.
/// The destination is a pointer to a field, the source is the value to store.
class Store : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Store; }
-
Store(SExpr *P, SExpr *V) : SExpr(COP_Store), Dest(P), Source(V) {}
Store(const Store &S, SExpr *P, SExpr *V) : SExpr(S), Dest(P), Source(V) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Store; }
+
SExpr *destination() { return Dest; } // Address to store to
const SExpr *destination() const { return Dest; }
@@ -1088,16 +1087,15 @@ private:
SExpr* Source;
};
-
/// If p is a reference to an array, then p[i] is a reference to the i'th
/// element of the array.
class ArrayIndex : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayIndex; }
-
ArrayIndex(SExpr *A, SExpr *N) : SExpr(COP_ArrayIndex), Array(A), Index(N) {}
ArrayIndex(const ArrayIndex &E, SExpr *A, SExpr *N)
- : SExpr(E), Array(A), Index(N) {}
+ : SExpr(E), Array(A), Index(N) {}
+
+ static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayIndex; }
SExpr *array() { return Array; }
const SExpr *array() const { return Array; }
@@ -1125,17 +1123,16 @@ private:
SExpr* Index;
};
-
/// Pointer arithmetic, restricted to arrays only.
/// If p is a reference to an array, then p + n, where n is an integer, is
/// a reference to a subarray.
class ArrayAdd : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayAdd; }
-
ArrayAdd(SExpr *A, SExpr *N) : SExpr(COP_ArrayAdd), Array(A), Index(N) {}
ArrayAdd(const ArrayAdd &E, SExpr *A, SExpr *N)
- : SExpr(E), Array(A), Index(N) {}
+ : SExpr(E), Array(A), Index(N) {}
+
+ static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayAdd; }
SExpr *array() { return Array; }
const SExpr *array() const { return Array; }
@@ -1163,18 +1160,18 @@ private:
SExpr* Index;
};
-
/// Simple arithmetic unary operations, e.g. negate and not.
/// These operations have no side-effects.
class UnaryOp : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_UnaryOp; }
-
UnaryOp(TIL_UnaryOpcode Op, SExpr *E) : SExpr(COP_UnaryOp), Expr0(E) {
Flags = Op;
}
+
UnaryOp(const UnaryOp &U, SExpr *E) : SExpr(U), Expr0(E) { Flags = U.Flags; }
+ static bool classof(const SExpr *E) { return E->opcode() == COP_UnaryOp; }
+
TIL_UnaryOpcode unaryOpcode() const {
return static_cast<TIL_UnaryOpcode>(Flags);
}
@@ -1201,22 +1198,22 @@ private:
SExpr* Expr0;
};
-
/// Simple arithmetic binary operations, e.g. +, -, etc.
/// These operations have no side effects.
class BinaryOp : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_BinaryOp; }
-
BinaryOp(TIL_BinaryOpcode Op, SExpr *E0, SExpr *E1)
: SExpr(COP_BinaryOp), Expr0(E0), Expr1(E1) {
Flags = Op;
}
+
BinaryOp(const BinaryOp &B, SExpr *E0, SExpr *E1)
: SExpr(B), Expr0(E0), Expr1(E1) {
Flags = B.Flags;
}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_BinaryOp; }
+
TIL_BinaryOpcode binaryOpcode() const {
return static_cast<TIL_BinaryOpcode>(Flags);
}
@@ -1251,17 +1248,16 @@ private:
SExpr* Expr1;
};
-
/// Cast expressions.
/// Cast expressions are essentially unary operations, but we treat them
/// as a distinct AST node because they only change the type of the result.
class Cast : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Cast; }
-
Cast(TIL_CastOpcode Op, SExpr *E) : SExpr(COP_Cast), Expr0(E) { Flags = Op; }
Cast(const Cast &C, SExpr *E) : SExpr(C), Expr0(E) { Flags = C.Flags; }
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Cast; }
+
TIL_CastOpcode castOpcode() const {
return static_cast<TIL_CastOpcode>(Flags);
}
@@ -1288,16 +1284,14 @@ private:
SExpr* Expr0;
};
-
class SCFG;
-
/// Phi Node, for code in SSA form.
/// Each Phi node has an array of possible values that it can take,
/// depending on where control flow comes from.
class Phi : public SExpr {
public:
- typedef SimpleArray<SExpr *> ValArray;
+ using ValArray = SimpleArray<SExpr *>;
// In minimal SSA form, all Phi nodes are MultiVal.
// During conversion to SSA, incomplete Phi nodes may be introduced, which
@@ -1308,14 +1302,11 @@ public:
PH_Incomplete // Phi node is incomplete
};
- static bool classof(const SExpr *E) { return E->opcode() == COP_Phi; }
+ Phi() : SExpr(COP_Phi) {}
+ Phi(MemRegionRef A, unsigned Nvals) : SExpr(COP_Phi), Values(A, Nvals) {}
+ Phi(const Phi &P, ValArray &&Vs) : SExpr(P), Values(std::move(Vs)) {}
- Phi()
- : SExpr(COP_Phi), Cvdecl(nullptr) {}
- Phi(MemRegionRef A, unsigned Nvals)
- : SExpr(COP_Phi), Values(A, Nvals), Cvdecl(nullptr) {}
- Phi(const Phi &P, ValArray &&Vs)
- : SExpr(P), Values(std::move(Vs)), Cvdecl(nullptr) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Phi; }
const ValArray &values() const { return Values; }
ValArray &values() { return Values; }
@@ -1324,19 +1315,18 @@ public:
void setStatus(Status s) { Flags = s; }
/// Return the clang declaration of the variable for this Phi node, if any.
- const clang::ValueDecl *clangDecl() const { return Cvdecl; }
+ const ValueDecl *clangDecl() const { return Cvdecl; }
/// Set the clang variable associated with this Phi node.
- void setClangDecl(const clang::ValueDecl *Cvd) { Cvdecl = Cvd; }
+ void setClangDecl(const ValueDecl *Cvd) { Cvdecl = Cvd; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
typename V::template Container<typename V::R_SExpr>
Nvs(Vs, Values.size());
- for (auto *Val : Values) {
+ for (const auto *Val : Values)
Nvs.push_back( Vs.traverse(Val, Vs.subExprCtx(Ctx)) );
- }
return Vs.reducePhi(*this, Nvs);
}
@@ -1348,31 +1338,28 @@ public:
private:
ValArray Values;
- const clang::ValueDecl* Cvdecl;
+ const ValueDecl* Cvdecl = nullptr;
};
-
/// Base class for basic block terminators: Branch, Goto, and Return.
class Terminator : public SExpr {
+protected:
+ Terminator(TIL_Opcode Op) : SExpr(Op) {}
+ Terminator(const SExpr &E) : SExpr(E) {}
+
public:
static bool classof(const SExpr *E) {
return E->opcode() >= COP_Goto && E->opcode() <= COP_Return;
}
-protected:
- Terminator(TIL_Opcode Op) : SExpr(Op) {}
- Terminator(const SExpr &E) : SExpr(E) {}
-
-public:
/// Return the list of basic blocks that this terminator can branch to.
- ArrayRef<BasicBlock*> successors();
+ ArrayRef<BasicBlock *> successors();
- ArrayRef<BasicBlock*> successors() const {
+ ArrayRef<BasicBlock *> successors() const {
return const_cast<Terminator*>(this)->successors();
}
};
-
/// Jump to another basic block.
/// A goto instruction is essentially a tail-recursive call into another
/// block. In addition to the block pointer, it specifies an index into the
@@ -1380,13 +1367,13 @@ public:
/// of the call.
class Goto : public Terminator {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Goto; }
-
Goto(BasicBlock *B, unsigned I)
: Terminator(COP_Goto), TargetBlock(B), Index(I) {}
Goto(const Goto &G, BasicBlock *B, unsigned I)
: Terminator(COP_Goto), TargetBlock(B), Index(I) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Goto; }
+
const BasicBlock *targetBlock() const { return TargetBlock; }
BasicBlock *targetBlock() { return TargetBlock; }
@@ -1394,9 +1381,7 @@ public:
unsigned index() const { return Index; }
/// Return the list of basic blocks that this terminator can branch to.
- ArrayRef<BasicBlock*> successors() {
- return TargetBlock;
- }
+ ArrayRef<BasicBlock *> successors() { return TargetBlock; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -1415,25 +1400,25 @@ private:
unsigned Index;
};
-
/// A conditional branch to two other blocks.
/// Note that unlike Goto, Branch does not have an index. The target blocks
/// must be child-blocks, and cannot have Phi nodes.
class Branch : public Terminator {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Branch; }
-
Branch(SExpr *C, BasicBlock *T, BasicBlock *E)
: Terminator(COP_Branch), Condition(C) {
Branches[0] = T;
Branches[1] = E;
}
+
Branch(const Branch &Br, SExpr *C, BasicBlock *T, BasicBlock *E)
: Terminator(Br), Condition(C) {
Branches[0] = T;
Branches[1] = E;
}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Branch; }
+
const SExpr *condition() const { return Condition; }
SExpr *condition() { return Condition; }
@@ -1463,24 +1448,21 @@ public:
}
private:
- SExpr* Condition;
+ SExpr *Condition;
BasicBlock *Branches[2];
};
-
/// Return from the enclosing function, passing the return value to the caller.
/// Only the exit block should end with a return statement.
class Return : public Terminator {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Return; }
-
Return(SExpr* Rval) : Terminator(COP_Return), Retval(Rval) {}
Return(const Return &R, SExpr* Rval) : Terminator(R), Retval(Rval) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Return; }
+
/// Return an empty list.
- ArrayRef<BasicBlock*> successors() {
- return None;
- }
+ ArrayRef<BasicBlock *> successors() { return None; }
SExpr *returnValue() { return Retval; }
const SExpr *returnValue() const { return Retval; }
@@ -1500,7 +1482,6 @@ private:
SExpr* Retval;
};
-
inline ArrayRef<BasicBlock*> Terminator::successors() {
switch (opcode()) {
case COP_Goto: return cast<Goto>(this)->successors();
@@ -1511,7 +1492,6 @@ inline ArrayRef<BasicBlock*> Terminator::successors() {
}
}
-
/// A basic block is part of an SCFG. It can be treated as a function in
/// continuation passing style. A block consists of a sequence of phi nodes,
/// which are "arguments" to the function, followed by a sequence of
@@ -1519,15 +1499,23 @@ inline ArrayRef<BasicBlock*> Terminator::successors() {
/// another basic block in the same SCFG.
class BasicBlock : public SExpr {
public:
- typedef SimpleArray<SExpr*> InstrArray;
- typedef SimpleArray<BasicBlock*> BlockArray;
+ using InstrArray = SimpleArray<SExpr *>;
+ using BlockArray = SimpleArray<BasicBlock *>;
// TopologyNodes are used to overlay tree structures on top of the CFG,
// such as dominator and postdominator trees. Each block is assigned an
// ID in the tree according to a depth-first search. Tree traversals are
// always up, towards the parents.
struct TopologyNode {
- TopologyNode() : NodeID(0), SizeOfSubTree(0), Parent(nullptr) {}
+ int NodeID = 0;
+
+ // Includes this node, so must be > 1.
+ int SizeOfSubTree = 0;
+
+ // Pointer to parent.
+ BasicBlock *Parent = nullptr;
+
+ TopologyNode() = default;
bool isParentOf(const TopologyNode& OtherNode) {
return OtherNode.NodeID > NodeID &&
@@ -1538,22 +1526,17 @@ public:
return OtherNode.NodeID >= NodeID &&
OtherNode.NodeID < NodeID + SizeOfSubTree;
}
-
- int NodeID;
- int SizeOfSubTree; // Includes this node, so must be > 1.
- BasicBlock *Parent; // Pointer to parent.
};
- static bool classof(const SExpr *E) { return E->opcode() == COP_BasicBlock; }
-
explicit BasicBlock(MemRegionRef A)
- : SExpr(COP_BasicBlock), Arena(A), CFGPtr(nullptr), BlockID(0),
- Visited(0), TermInstr(nullptr) {}
+ : SExpr(COP_BasicBlock), Arena(A), BlockID(0), Visited(false) {}
BasicBlock(BasicBlock &B, MemRegionRef A, InstrArray &&As, InstrArray &&Is,
Terminator *T)
- : SExpr(COP_BasicBlock), Arena(A), CFGPtr(nullptr), BlockID(0),Visited(0),
+ : SExpr(COP_BasicBlock), Arena(A), BlockID(0), Visited(false),
Args(std::move(As)), Instrs(std::move(Is)), TermInstr(T) {}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_BasicBlock; }
+
/// Returns the block ID. Every block has a unique ID in the CFG.
int blockID() const { return BlockID; }
@@ -1600,11 +1583,13 @@ public:
Args.reserveCheck(1, Arena);
Args.push_back(V);
}
+
/// Add a new instruction.
void addInstruction(SExpr *V) {
Instrs.reserveCheck(1, Arena);
Instrs.push_back(V);
}
+
// Add a new predecessor, and return the phi-node index for it.
// Will add an argument to all phi-nodes, initialized to nullptr.
unsigned addPredecessor(BasicBlock *Pred);
@@ -1632,11 +1617,11 @@ public:
// Entering the basic block should do any scope initialization.
Vs.enterBasicBlock(*this);
- for (auto *E : Args) {
+ for (const auto *E : Args) {
auto Ne = Vs.traverse(E, Vs.subExprCtx(Ctx));
Nas.push_back(Ne);
}
- for (auto *E : Instrs) {
+ for (const auto *E : Instrs) {
auto Ne = Vs.traverse(E, Vs.subExprCtx(Ctx));
Nis.push_back(Ne);
}
@@ -1657,43 +1642,56 @@ public:
private:
friend class SCFG;
- int renumberInstrs(int id); // assign unique ids to all instructions
- int topologicalSort(SimpleArray<BasicBlock*>& Blocks, int ID);
- int topologicalFinalSort(SimpleArray<BasicBlock*>& Blocks, int ID);
+ // assign unique ids to all instructions
+ int renumberInstrs(int id);
+
+ int topologicalSort(SimpleArray<BasicBlock *> &Blocks, int ID);
+ int topologicalFinalSort(SimpleArray<BasicBlock *> &Blocks, int ID);
void computeDominator();
void computePostDominator();
-private:
- MemRegionRef Arena; // The arena used to allocate this block.
- SCFG *CFGPtr; // The CFG that contains this block.
- int BlockID : 31; // unique id for this BB in the containing CFG.
- // IDs are in topological order.
- bool Visited : 1; // Bit to determine if a block has been visited
- // during a traversal.
- BlockArray Predecessors; // Predecessor blocks in the CFG.
- InstrArray Args; // Phi nodes. One argument per predecessor.
- InstrArray Instrs; // Instructions.
- Terminator* TermInstr; // Terminating instruction
-
- TopologyNode DominatorNode; // The dominator tree
- TopologyNode PostDominatorNode; // The post-dominator tree
-};
+ // The arena used to allocate this block.
+ MemRegionRef Arena;
+
+ // The CFG that contains this block.
+ SCFG *CFGPtr = nullptr;
+
+ // Unique ID for this BB in the containing CFG. IDs are in topological order.
+ int BlockID : 31;
+ // Bit to determine if a block has been visited during a traversal.
+ bool Visited : 1;
+
+ // Predecessor blocks in the CFG.
+ BlockArray Predecessors;
+
+ // Phi nodes. One argument per predecessor.
+ InstrArray Args;
+
+ // Instructions.
+ InstrArray Instrs;
+
+ // Terminating instruction.
+ Terminator *TermInstr = nullptr;
+
+ // The dominator tree.
+ TopologyNode DominatorNode;
+
+ // The post-dominator tree.
+ TopologyNode PostDominatorNode;
+};
/// An SCFG is a control-flow graph. It consists of a set of basic blocks,
/// each of which terminates in a branch to another basic block. There is one
/// entry point, and one exit point.
class SCFG : public SExpr {
public:
- typedef SimpleArray<BasicBlock *> BlockArray;
- typedef BlockArray::iterator iterator;
- typedef BlockArray::const_iterator const_iterator;
-
- static bool classof(const SExpr *E) { return E->opcode() == COP_SCFG; }
+ using BlockArray = SimpleArray<BasicBlock *>;
+ using iterator = BlockArray::iterator;
+ using const_iterator = BlockArray::const_iterator;
SCFG(MemRegionRef A, unsigned Nblocks)
- : SExpr(COP_SCFG), Arena(A), Blocks(A, Nblocks),
- Entry(nullptr), Exit(nullptr), NumInstructions(0), Normal(false) {
+ : SExpr(COP_SCFG), Arena(A), Blocks(A, Nblocks) {
Entry = new (A) BasicBlock(A);
Exit = new (A) BasicBlock(A);
auto *V = new (A) Phi();
@@ -1702,12 +1700,14 @@ public:
add(Entry);
add(Exit);
}
+
SCFG(const SCFG &Cfg, BlockArray &&Ba) // steals memory from Ba
- : SExpr(COP_SCFG), Arena(Cfg.Arena), Blocks(std::move(Ba)),
- Entry(nullptr), Exit(nullptr), NumInstructions(0), Normal(false) {
+ : SExpr(COP_SCFG), Arena(Cfg.Arena), Blocks(std::move(Ba)) {
// TODO: set entry and exit!
}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_SCFG; }
+
/// Return true if this CFG is valid.
bool valid() const { return Entry && Exit && Blocks.size() > 0; }
@@ -1756,7 +1756,7 @@ public:
Vs.enterCFG(*this);
typename V::template Container<BasicBlock *> Bbs(Vs, Blocks.size());
- for (auto *B : Blocks) {
+ for (const auto *B : Blocks) {
Bbs.push_back( B->traverse(Vs, Vs.subExprCtx(Ctx)) );
}
Vs.exitCFG(*this);
@@ -1770,27 +1770,25 @@ public:
}
private:
- void renumberInstrs(); // assign unique ids to all instructions
+ // assign unique ids to all instructions
+ void renumberInstrs();
-private:
MemRegionRef Arena;
- BlockArray Blocks;
- BasicBlock *Entry;
- BasicBlock *Exit;
- unsigned NumInstructions;
- bool Normal;
+ BlockArray Blocks;
+ BasicBlock *Entry = nullptr;
+ BasicBlock *Exit = nullptr;
+ unsigned NumInstructions = 0;
+ bool Normal = false;
};
-
-
/// An identifier, e.g. 'foo' or 'x'.
/// This is a pseduo-term; it will be lowered to a variable or projection.
class Identifier : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Identifier; }
+ Identifier(StringRef Id): SExpr(COP_Identifier), Name(Id) {}
+ Identifier(const Identifier &) = default;
- Identifier(StringRef Id): SExpr(COP_Identifier), Name(Id) { }
- Identifier(const Identifier& I) : SExpr(I), Name(I.Name) { }
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Identifier; }
StringRef name() const { return Name; }
@@ -1808,19 +1806,16 @@ private:
StringRef Name;
};
-
/// An if-then-else expression.
/// This is a pseduo-term; it will be lowered to a branch in a CFG.
class IfThenElse : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_IfThenElse; }
-
IfThenElse(SExpr *C, SExpr *T, SExpr *E)
- : SExpr(COP_IfThenElse), Condition(C), ThenExpr(T), ElseExpr(E)
- { }
+ : SExpr(COP_IfThenElse), Condition(C), ThenExpr(T), ElseExpr(E) {}
IfThenElse(const IfThenElse &I, SExpr *C, SExpr *T, SExpr *E)
- : SExpr(I), Condition(C), ThenExpr(T), ElseExpr(E)
- { }
+ : SExpr(I), Condition(C), ThenExpr(T), ElseExpr(E) {}
+
+ static bool classof(const SExpr *E) { return E->opcode() == COP_IfThenElse; }
SExpr *condition() { return Condition; } // Address to store to
const SExpr *condition() const { return Condition; }
@@ -1856,20 +1851,20 @@ private:
SExpr* ElseExpr;
};
-
/// A let-expression, e.g. let x=t; u.
/// This is a pseduo-term; it will be lowered to instructions in a CFG.
class Let : public SExpr {
public:
- static bool classof(const SExpr *E) { return E->opcode() == COP_Let; }
-
Let(Variable *Vd, SExpr *Bd) : SExpr(COP_Let), VarDecl(Vd), Body(Bd) {
Vd->setKind(Variable::VK_Let);
}
+
Let(const Let &L, Variable *Vd, SExpr *Bd) : SExpr(L), VarDecl(Vd), Body(Bd) {
Vd->setKind(Variable::VK_Let);
}
+ static bool classof(const SExpr *E) { return E->opcode() == COP_Let; }
+
Variable *variableDecl() { return VarDecl; }
const Variable *variableDecl() const { return VarDecl; }
@@ -1904,15 +1899,13 @@ private:
SExpr* Body;
};
-
-
const SExpr *getCanonicalVal(const SExpr *E);
SExpr* simplifyToCanonicalVal(SExpr *E);
void simplifyIncompleteArg(til::Phi *Ph);
+} // namespace til
+} // namespace threadSafety
-} // end namespace til
-} // end namespace threadSafety
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTIL_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
index 705fe910d0923..49031010a75b6 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
@@ -1,4 +1,4 @@
-//===- ThreadSafetyTraverse.h ----------------------------------*- C++ --*-===//
+//===- ThreadSafetyTraverse.h -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,7 +17,13 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTRAVERSE_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTRAVERSE_H
-#include "ThreadSafetyTIL.h"
+#include "clang/AST/Decl.h"
+#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
+#include "clang/Analysis/Analyses/ThreadSafetyUtil.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include <cstdint>
#include <ostream>
namespace clang {
@@ -26,7 +32,7 @@ namespace til {
// Defines an interface used to traverse SExprs. Traversals have been made as
// generic as possible, and are intended to handle any kind of pass over the
-// AST, e.g. visiters, copying, non-destructive rewriting, destructive
+// AST, e.g. visitors, copying, non-destructive rewriting, destructive
// (in-place) rewriting, hashing, typing, etc.
//
// Traversals implement the functional notion of a "fold" operation on SExprs.
@@ -92,21 +98,27 @@ public:
#undef TIL_OPCODE_DEF
};
-
// Base class for simple reducers that don't much care about the context.
class SimpleReducerBase {
public:
enum TraversalKind {
- TRV_Normal, // ordinary subexpressions
- TRV_Decl, // declarations (e.g. function bodies)
- TRV_Lazy, // expressions that require lazy evaluation
- TRV_Type // type expressions
+ // Ordinary subexpressions.
+ TRV_Normal,
+
+ // Declarations (e.g. function bodies).
+ TRV_Decl,
+
+ // Expressions that require lazy evaluation.
+ TRV_Lazy,
+
+ // Type expressions.
+ TRV_Type
};
// R_Ctx defines a "context" for the traversal, which encodes information
// about where a term appears. This can be used to encoding the
// "current continuation" for CPS transforms, or other information.
- typedef TraversalKind R_Ctx;
+ using R_Ctx = TraversalKind;
// Create context for an ordinary subexpression.
R_Ctx subExprCtx(R_Ctx Ctx) { return TRV_Normal; }
@@ -123,14 +135,13 @@ public:
R_Ctx typeCtx(R_Ctx Ctx) { return TRV_Type; }
};
-
// Base class for traversals that rewrite an SExpr to another SExpr.
class CopyReducerBase : public SimpleReducerBase {
public:
// R_SExpr is the result type for a traversal.
// A copy or non-destructive rewrite returns a newly allocated term.
- typedef SExpr *R_SExpr;
- typedef BasicBlock *R_BasicBlock;
+ using R_SExpr = SExpr *;
+ using R_BasicBlock = BasicBlock *;
// Container is a minimal interface used to store results when traversing
// SExprs of variable arity, such as Phi, Goto, and SCFG.
@@ -151,32 +162,31 @@ protected:
MemRegionRef Arena;
};
-
// Base class for visit traversals.
class VisitReducerBase : public SimpleReducerBase {
public:
// A visitor returns a bool, representing success or failure.
- typedef bool R_SExpr;
- typedef bool R_BasicBlock;
+ using R_SExpr = bool;
+ using R_BasicBlock = bool;
// A visitor "container" is a single bool, which accumulates success.
template <class T> class Container {
public:
- Container(VisitReducerBase &S, unsigned N) : Success(true) {}
- void push_back(bool E) { Success = Success && E; }
+ bool Success = true;
- bool Success;
+ Container(VisitReducerBase &S, unsigned N) {}
+
+ void push_back(bool E) { Success = Success && E; }
};
};
-
// Implements a traversal that visits each subexpression, and returns either
// true or false.
template <class Self>
class VisitReducer : public Traversal<Self, VisitReducerBase>,
public VisitReducerBase {
public:
- VisitReducer() {}
+ VisitReducer() = default;
public:
R_SExpr reduceNull() { return true; }
@@ -191,54 +201,70 @@ public:
R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0) {
return Nvd && E0;
}
+
R_SExpr reduceSFunction(SFunction &Orig, Variable *Nvd, R_SExpr E0) {
return Nvd && E0;
}
+
R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1) {
return E0 && E1;
}
+
R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1) {
return E0 && E1;
}
+
R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1) {
return E0 && E1;
}
+
R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1) {
return E0 && E1;
}
+
R_SExpr reduceProject(Project &Orig, R_SExpr E0) { return E0; }
R_SExpr reduceCall(Call &Orig, R_SExpr E0) { return E0; }
R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0) { return E0; }
R_SExpr reduceLoad(Load &Orig, R_SExpr E0) { return E0; }
R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1) { return E0 && E1; }
+
R_SExpr reduceArrayIndex(Store &Orig, R_SExpr E0, R_SExpr E1) {
return E0 && E1;
}
+
R_SExpr reduceArrayAdd(Store &Orig, R_SExpr E0, R_SExpr E1) {
return E0 && E1;
}
+
R_SExpr reduceUnaryOp(UnaryOp &Orig, R_SExpr E0) { return E0; }
+
R_SExpr reduceBinaryOp(BinaryOp &Orig, R_SExpr E0, R_SExpr E1) {
return E0 && E1;
}
+
R_SExpr reduceCast(Cast &Orig, R_SExpr E0) { return E0; }
R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> Bbs) {
return Bbs.Success;
}
+
R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container<R_SExpr> &As,
Container<R_SExpr> &Is, R_SExpr T) {
return (As.Success && Is.Success && T);
}
+
R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) {
return As.Success;
}
+
R_SExpr reduceGoto(Goto &Orig, BasicBlock *B) {
return true;
}
+
R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) {
return C;
}
+
R_SExpr reduceReturn(Return &O, R_SExpr E) {
return E;
}
@@ -246,9 +272,11 @@ public:
R_SExpr reduceIdentifier(Identifier &Orig) {
return true;
}
+
R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E) {
return C && T && E;
}
+
R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B) {
return Nvd && B;
}
@@ -260,7 +288,7 @@ public:
void enterBasicBlock(BasicBlock &BB) {}
void exitBasicBlock(BasicBlock &BB) {}
- Variable *reduceVariableRef (Variable *Ovd) { return Ovd; }
+ Variable *reduceVariableRef(Variable *Ovd) { return Ovd; }
BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; }
public:
@@ -278,7 +306,6 @@ private:
bool Success;
};
-
// Basic class for comparison operations over expressions.
template <typename Self>
class Comparator {
@@ -298,19 +325,18 @@ public:
}
};
-
class EqualsComparator : public Comparator<EqualsComparator> {
public:
// Result type for the comparison, e.g. bool for simple equality,
// or int for lexigraphic comparison (-1, 0, 1). Must have one value which
// denotes "true".
- typedef bool CType;
+ using CType = bool;
CType trueResult() { return true; }
bool notTrue(CType ct) { return !ct; }
- bool compareIntegers(unsigned i, unsigned j) { return i == j; }
- bool compareStrings (StringRef s, StringRef r) { return s == r; }
+ bool compareIntegers(unsigned i, unsigned j) { return i == j; }
+ bool compareStrings (StringRef s, StringRef r) { return s == r; }
bool comparePointers(const void* P, const void* Q) { return P == Q; }
bool compare(const SExpr *E1, const SExpr* E2) {
@@ -320,10 +346,10 @@ public:
}
// TODO -- handle alpha-renaming of variables
- void enterScope(const Variable* V1, const Variable* V2) { }
- void leaveScope() { }
+ void enterScope(const Variable *V1, const Variable *V2) {}
+ void leaveScope() {}
- bool compareVariableRefs(const Variable* V1, const Variable* V2) {
+ bool compareVariableRefs(const Variable *V1, const Variable *V2) {
return V1 == V2;
}
@@ -333,23 +359,21 @@ public:
}
};
-
-
class MatchComparator : public Comparator<MatchComparator> {
public:
// Result type for the comparison, e.g. bool for simple equality,
// or int for lexigraphic comparison (-1, 0, 1). Must have one value which
// denotes "true".
- typedef bool CType;
+ using CType = bool;
CType trueResult() { return true; }
bool notTrue(CType ct) { return !ct; }
- bool compareIntegers(unsigned i, unsigned j) { return i == j; }
- bool compareStrings (StringRef s, StringRef r) { return s == r; }
- bool comparePointers(const void* P, const void* Q) { return P == Q; }
+ bool compareIntegers(unsigned i, unsigned j) { return i == j; }
+ bool compareStrings (StringRef s, StringRef r) { return s == r; }
+ bool comparePointers(const void *P, const void *Q) { return P == Q; }
- bool compare(const SExpr *E1, const SExpr* E2) {
+ bool compare(const SExpr *E1, const SExpr *E2) {
// Wildcards match anything.
if (E1->opcode() == COP_Wildcard || E2->opcode() == COP_Wildcard)
return true;
@@ -360,8 +384,8 @@ public:
}
// TODO -- handle alpha-renaming of variables
- void enterScope(const Variable* V1, const Variable* V2) { }
- void leaveScope() { }
+ void enterScope(const Variable* V1, const Variable* V2) {}
+ void leaveScope() {}
bool compareVariableRefs(const Variable* V1, const Variable* V2) {
return V1 == V2;
@@ -373,8 +397,6 @@ public:
}
};
-
-
// inline std::ostream& operator<<(std::ostream& SS, StringRef R) {
// return SS.write(R.data(), R.size());
// }
@@ -383,14 +405,18 @@ public:
template <typename Self, typename StreamType>
class PrettyPrinter {
private:
- bool Verbose; // Print out additional information
- bool Cleanup; // Omit redundant decls.
- bool CStyle; // Print exprs in C-like syntax.
+ // Print out additional information.
+ bool Verbose;
+
+ // Omit redundant decls.
+ bool Cleanup;
+
+ // Print exprs in C-like syntax.
+ bool CStyle;
public:
PrettyPrinter(bool V = false, bool C = true, bool CS = true)
- : Verbose(V), Cleanup(C), CStyle(CS)
- {}
+ : Verbose(V), Cleanup(C), CStyle(CS) {}
static void print(const SExpr *E, StreamType &SS) {
Self printer;
@@ -470,7 +496,6 @@ protected:
}
}
-
void printSExpr(const SExpr *E, StreamType &SS, unsigned P, bool Sub=true) {
if (!E) {
self()->printNull(SS);
@@ -531,18 +556,16 @@ protected:
else {
ValueType VT = E->valueType();
switch (VT.Base) {
- case ValueType::BT_Void: {
+ case ValueType::BT_Void:
SS << "void";
return;
- }
- case ValueType::BT_Bool: {
+ case ValueType::BT_Bool:
if (E->as<bool>().value())
SS << "true";
else
SS << "false";
return;
- }
- case ValueType::BT_Int: {
+ case ValueType::BT_Int:
switch (VT.Size) {
case ValueType::ST_8:
if (VT.Signed)
@@ -572,8 +595,7 @@ protected:
break;
}
break;
- }
- case ValueType::BT_Float: {
+ case ValueType::BT_Float:
switch (VT.Size) {
case ValueType::ST_32:
printLiteralT(&E->as<float>(), SS);
@@ -585,22 +607,18 @@ protected:
break;
}
break;
- }
- case ValueType::BT_String: {
+ case ValueType::BT_String:
SS << "\"";
printLiteralT(&E->as<StringRef>(), SS);
SS << "\"";
return;
- }
- case ValueType::BT_Pointer: {
+ case ValueType::BT_Pointer:
SS << "#ptr";
return;
- }
- case ValueType::BT_ValueRef: {
+ case ValueType::BT_ValueRef:
SS << "#vref";
return;
}
- }
}
SS << "#lit";
}
@@ -688,8 +706,8 @@ protected:
void printProject(const Project *E, StreamType &SS) {
if (CStyle) {
// Omit the this->
- if (const SApply *SAP = dyn_cast<SApply>(E->record())) {
- if (const Variable *V = dyn_cast<Variable>(SAP->sfun())) {
+ if (const auto *SAP = dyn_cast<SApply>(E->record())) {
+ if (const auto *V = dyn_cast<Variable>(SAP->sfun())) {
if (!SAP->isDelegation() && V->kind() == Variable::VK_SFun) {
SS << E->slotName();
return;
@@ -704,12 +722,10 @@ protected:
}
}
self()->printSExpr(E->record(), SS, Prec_Postfix);
- if (CStyle && E->isArrow()) {
+ if (CStyle && E->isArrow())
SS << "->";
- }
- else {
+ else
SS << ".";
- }
SS << E->slotName();
}
@@ -780,18 +796,16 @@ protected:
void printSCFG(const SCFG *E, StreamType &SS) {
SS << "CFG {\n";
- for (auto BBI : *E) {
+ for (const auto *BBI : *E)
printBasicBlock(BBI, SS);
- }
SS << "}";
newline(SS);
}
-
void printBBInstr(const SExpr *E, StreamType &SS) {
bool Sub = false;
if (E->opcode() == COP_Variable) {
- auto *V = cast<Variable>(E);
+ const auto *V = cast<Variable>(E);
SS << "let " << V->name() << V->id() << " = ";
E = V->definition();
Sub = true;
@@ -810,10 +824,10 @@ protected:
SS << " BB_" << E->parent()->blockID();
newline(SS);
- for (auto *A : E->arguments())
+ for (const auto *A : E->arguments())
printBBInstr(A, SS);
- for (auto *I : E->instructions())
+ for (const auto *I : E->instructions())
printBBInstr(I, SS);
const SExpr *T = E->terminator();
@@ -831,7 +845,7 @@ protected:
self()->printSExpr(E->values()[0], SS, Prec_MAX);
else {
unsigned i = 0;
- for (auto V : E->values()) {
+ for (const auto *V : E->values()) {
if (i++ > 0)
SS << ", ";
self()->printSExpr(V, SS, Prec_MAX);
@@ -890,13 +904,10 @@ protected:
}
};
+class StdPrinter : public PrettyPrinter<StdPrinter, std::ostream> {};
-class StdPrinter : public PrettyPrinter<StdPrinter, std::ostream> { };
-
-
-
-} // end namespace til
-} // end namespace threadSafety
-} // end namespace clang
+} // namespace til
+} // namespace threadSafety
+} // namespace clang
-#endif // LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTRAVERSE_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
index cb80ce5da8d2f..16583939d5423 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
@@ -1,4 +1,4 @@
-//===- ThreadSafetyUtil.h --------------------------------------*- C++ --*-===//
+//===- ThreadSafetyUtil.h ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,18 +14,23 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYUTIL_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYUTIL_H
-#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/AlignOf.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstddef>
+#include <cstring>
+#include <iterator>
#include <ostream>
-#include <utility>
+#include <string>
#include <vector>
namespace clang {
+
+class Expr;
+
namespace threadSafety {
namespace til {
@@ -41,7 +46,7 @@ private:
};
public:
- MemRegionRef() : Allocator(nullptr) {}
+ MemRegionRef() = default;
MemRegionRef(llvm::BumpPtrAllocator *A) : Allocator(A) {}
void *allocate(size_t Sz) {
@@ -55,12 +60,13 @@ public:
}
private:
- llvm::BumpPtrAllocator *Allocator;
+ llvm::BumpPtrAllocator *Allocator = nullptr;
};
-} // end namespace til
-} // end namespace threadSafety
-} // end namespace clang
+} // namespace til
+} // namespace threadSafety
+
+} // namespace clang
inline void *operator new(size_t Sz,
clang::threadSafety::til::MemRegionRef &R) {
@@ -70,10 +76,7 @@ inline void *operator new(size_t Sz,
namespace clang {
namespace threadSafety {
-std::string getSourceLiteralString(const clang::Expr *CE);
-
-using llvm::StringRef;
-using clang::SourceLocation;
+std::string getSourceLiteralString(const Expr *CE);
namespace til {
@@ -81,11 +84,13 @@ namespace til {
// suitable for use with bump pointer allocation.
template <class T> class SimpleArray {
public:
- SimpleArray() : Data(nullptr), Size(0), Capacity(0) {}
+ SimpleArray() = default;
SimpleArray(T *Dat, size_t Cp, size_t Sz = 0)
: Data(Dat), Size(Sz), Capacity(Cp) {}
SimpleArray(MemRegionRef A, size_t Cp)
- : Data(Cp == 0 ? nullptr : A.allocateT<T>(Cp)), Size(0), Capacity(Cp) {}
+ : Data(Cp == 0 ? nullptr : A.allocateT<T>(Cp)), Capacity(Cp) {}
+ SimpleArray(const SimpleArray<T> &A) = delete;
+
SimpleArray(SimpleArray<T> &&A)
: Data(A.Data), Size(A.Size), Capacity(A.Capacity) {
A.Data = nullptr;
@@ -123,10 +128,10 @@ public:
reserve(u_max(Size + N, Capacity * 2), A);
}
- typedef T *iterator;
- typedef const T *const_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ using iterator = T *;
+ using const_iterator = const T *;
+ using reverse_iterator = std::reverse_iterator<iterator>;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
size_t size() const { return Size; }
size_t capacity() const { return Capacity; }
@@ -135,27 +140,30 @@ public:
assert(i < Size && "Array index out of bounds.");
return Data[i];
}
+
const T &operator[](unsigned i) const {
assert(i < Size && "Array index out of bounds.");
return Data[i];
}
+
T &back() {
assert(Size && "No elements in the array.");
return Data[Size - 1];
}
+
const T &back() const {
assert(Size && "No elements in the array.");
return Data[Size - 1];
}
iterator begin() { return Data; }
- iterator end() { return Data + Size; }
+ iterator end() { return Data + Size; }
const_iterator begin() const { return Data; }
- const_iterator end() const { return Data + Size; }
+ const_iterator end() const { return Data + Size; }
const_iterator cbegin() const { return Data; }
- const_iterator cend() const { return Data + Size; }
+ const_iterator cend() const { return Data + Size; }
reverse_iterator rbegin() { return reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
@@ -163,6 +171,7 @@ public:
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
+
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
@@ -198,6 +207,7 @@ public:
llvm::iterator_range<reverse_iterator> reverse() {
return llvm::make_range(rbegin(), rend());
}
+
llvm::iterator_range<const_reverse_iterator> reverse() const {
return llvm::make_range(rbegin(), rend());
}
@@ -209,14 +219,12 @@ private:
static const size_t InitialCapacity = 4;
- SimpleArray(const SimpleArray<T> &A) = delete;
-
- T *Data;
- size_t Size;
- size_t Capacity;
+ T *Data = nullptr;
+ size_t Size = 0;
+ size_t Capacity = 0;
};
-} // end namespace til
+} // namespace til
// A copy on write vector.
// The vector can be in one of three states:
@@ -228,20 +236,28 @@ template<typename T>
class CopyOnWriteVector {
class VectorData {
public:
- VectorData() : NumRefs(1) { }
- VectorData(const VectorData &VD) : NumRefs(1), Vect(VD.Vect) { }
-
- unsigned NumRefs;
+ unsigned NumRefs = 1;
std::vector<T> Vect;
- };
- // No copy constructor or copy assignment. Use clone() with move assignment.
- CopyOnWriteVector(const CopyOnWriteVector &V) = delete;
- void operator=(const CopyOnWriteVector &V) = delete;
+ VectorData() = default;
+ VectorData(const VectorData &VD) : Vect(VD.Vect) {}
+ };
public:
- CopyOnWriteVector() : Data(nullptr) {}
+ CopyOnWriteVector() = default;
CopyOnWriteVector(CopyOnWriteVector &&V) : Data(V.Data) { V.Data = nullptr; }
+
+ CopyOnWriteVector &operator=(CopyOnWriteVector &&V) {
+ destroy();
+ Data = V.Data;
+ V.Data = nullptr;
+ return *this;
+ }
+
+ // No copy constructor or copy assignment. Use clone() with move assignment.
+ CopyOnWriteVector(const CopyOnWriteVector &) = delete;
+ CopyOnWriteVector &operator=(const CopyOnWriteVector &) = delete;
+
~CopyOnWriteVector() { destroy(); }
// Returns true if this holds a valid vector.
@@ -283,14 +299,7 @@ public:
// Create a lazy copy of this vector.
CopyOnWriteVector clone() { return CopyOnWriteVector(Data); }
- CopyOnWriteVector &operator=(CopyOnWriteVector &&V) {
- destroy();
- Data = V.Data;
- V.Data = nullptr;
- return *this;
- }
-
- typedef typename std::vector<T>::const_iterator const_iterator;
+ using const_iterator = typename std::vector<T>::const_iterator;
const std::vector<T> &elements() const { return Data->Vect; }
@@ -336,14 +345,14 @@ private:
++Data->NumRefs;
}
- VectorData *Data;
+ VectorData *Data = nullptr;
};
inline std::ostream& operator<<(std::ostream& ss, const StringRef str) {
return ss.write(str.data(), str.size());
}
-} // end namespace threadSafety
-} // end namespace clang
+} // namespace threadSafety
+} // namespace clang
#endif // LLVM_CLANG_THREAD_SAFETY_UTIL_H
diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h
index 53ff20c23560c..79d89e0633fd0 100644
--- a/include/clang/Analysis/Analyses/UninitializedValues.h
+++ b/include/clang/Analysis/Analyses/UninitializedValues.h
@@ -1,4 +1,4 @@
-//= UninitializedValues.h - Finding uses of uninitialized values -*- C++ -*-==//
+//=- UninitializedValues.h - Finding uses of uninitialized values -*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
@@ -15,7 +15,7 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
-#include "clang/AST/Stmt.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallVector.h"
namespace clang {
@@ -24,6 +24,7 @@ class AnalysisDeclContext;
class CFG;
class DeclContext;
class Expr;
+class Stmt;
class VarDecl;
/// A use of a variable, which might be uninitialized.
@@ -39,10 +40,10 @@ private:
const Expr *User;
/// Is this use uninitialized whenever the function is called?
- bool UninitAfterCall;
+ bool UninitAfterCall = false;
/// Is this use uninitialized whenever the variable declaration is reached?
- bool UninitAfterDecl;
+ bool UninitAfterDecl = false;
/// Does this use always see an uninitialized value?
bool AlwaysUninit;
@@ -53,8 +54,7 @@ private:
public:
UninitUse(const Expr *User, bool AlwaysUninit)
- : User(User), UninitAfterCall(false), UninitAfterDecl(false),
- AlwaysUninit(AlwaysUninit) {}
+ : User(User), AlwaysUninit(AlwaysUninit) {}
void addUninitBranch(Branch B) {
UninitBranches.push_back(B);
@@ -70,14 +70,18 @@ public:
enum Kind {
/// The use might be uninitialized.
Maybe,
+
/// The use is uninitialized whenever a certain branch is taken.
Sometimes,
+
/// The use is uninitialized the first time it is reached after we reach
/// the variable's declaration.
AfterDecl,
+
/// The use is uninitialized the first time it is reached after the function
/// is called.
AfterCall,
+
/// The use is always uninitialized.
Always
};
@@ -90,7 +94,8 @@ public:
!branch_empty() ? Sometimes : Maybe;
}
- typedef SmallVectorImpl<Branch>::const_iterator branch_iterator;
+ using branch_iterator = SmallVectorImpl<Branch>::const_iterator;
+
/// Branches which inevitably result in the variable being used uninitialized.
branch_iterator branch_begin() const { return UninitBranches.begin(); }
branch_iterator branch_end() const { return UninitBranches.end(); }
@@ -99,7 +104,7 @@ public:
class UninitVariablesHandler {
public:
- UninitVariablesHandler() {}
+ UninitVariablesHandler() = default;
virtual ~UninitVariablesHandler();
/// Called when the uninitialized variable is used at the given expression.
@@ -122,5 +127,6 @@ void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
UninitVariablesHandler &handler,
UninitVariablesAnalysisStats &stats);
-}
-#endif
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_UNINITIALIZEDVALUES_H
diff --git a/include/clang/Analysis/AnalysisDeclContext.h b/include/clang/Analysis/AnalysisDeclContext.h
index 03ff4a9516da0..8c391b5ee1e5d 100644
--- a/include/clang/Analysis/AnalysisDeclContext.h
+++ b/include/clang/Analysis/AnalysisDeclContext.h
@@ -1,4 +1,4 @@
-//=== AnalysisDeclContext.h - Analysis context for Path Sens analysis --*- C++ -*-//
+// AnalysisDeclContext.h - Analysis context for Path Sens analysis -*- C++ -*-//
//
// The LLVM Compiler Infrastructure
//
@@ -15,37 +15,42 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
#define LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
-#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/Analysis/BodyFarm.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/CodeInjector.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
+#include <functional>
#include <memory>
namespace clang {
-class Stmt;
+class AnalysisDeclContextManager;
+class ASTContext;
+class BlockDecl;
+class BlockInvocationContext;
class CFGReverseBlockReachabilityAnalysis;
class CFGStmtMap;
-class LiveVariables;
-class ManagedAnalysis;
+class ImplicitParamDecl;
+class LocationContext;
+class LocationContextManager;
class ParentMap;
class PseudoConstantAnalysis;
-class LocationContextManager;
class StackFrameContext;
-class BlockInvocationContext;
-class AnalysisDeclContextManager;
-class LocationContext;
-
-namespace idx { class TranslationUnit; }
+class Stmt;
+class VarDecl;
/// The base class of a hierarchy of objects representing analyses tied
/// to AnalysisDeclContext.
class ManagedAnalysis {
protected:
- ManagedAnalysis() {}
+ ManagedAnalysis() = default;
+
public:
virtual ~ManagedAnalysis();
@@ -61,7 +66,6 @@ public:
// which creates the analysis object given an AnalysisDeclContext.
};
-
/// AnalysisDeclContext contains the context data for the function or method
/// under analysis.
class AnalysisDeclContext {
@@ -75,18 +79,19 @@ class AnalysisDeclContext {
std::unique_ptr<CFGStmtMap> cfgStmtMap;
CFG::BuildOptions cfgBuildOptions;
- CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
+ CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs = nullptr;
- bool builtCFG, builtCompleteCFG;
+ bool builtCFG = false;
+ bool builtCompleteCFG = false;
std::unique_ptr<ParentMap> PM;
std::unique_ptr<PseudoConstantAnalysis> PCA;
std::unique_ptr<CFGReverseBlockReachabilityAnalysis> CFA;
llvm::BumpPtrAllocator A;
- llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
+ llvm::DenseMap<const BlockDecl *,void *> *ReferencedBlockVars = nullptr;
- void *ManagedAnalyses;
+ void *ManagedAnalyses = nullptr;
public:
AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
@@ -130,22 +135,22 @@ public:
void registerForcedBlockExpression(const Stmt *stmt);
const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
- /// \brief Get the body of the Declaration.
+ /// Get the body of the Declaration.
Stmt *getBody() const;
- /// \brief Get the body of the Declaration.
+ /// Get the body of the Declaration.
/// \param[out] IsAutosynthesized Specifies if the body is auto-generated
/// by the BodyFarm.
Stmt *getBody(bool &IsAutosynthesized) const;
- /// \brief Checks if the body of the Decl is generated by the BodyFarm.
+ /// Checks if the body of the Decl is generated by the BodyFarm.
///
/// Note, the lookup is not free. We are going to call getBody behind
/// the scenes.
/// \sa getBody
bool isBodyAutosynthesized() const;
- /// \brief Checks if the body of the Decl is generated by the BodyFarm from a
+ /// Checks if the body of the Decl is generated by the BodyFarm from a
/// model file.
///
/// Note, the lookup is not free. We are going to call getBody behind
@@ -164,7 +169,7 @@ public:
void dumpCFG(bool ShowColors);
- /// \brief Returns true if we have built a CFG for this analysis context.
+ /// Returns true if we have built a CFG for this analysis context.
/// Note that this doesn't correspond to whether or not a valid CFG exists, it
/// corresponds to whether we *attempted* to build one.
bool isCFGBuilt() const { return builtCFG; }
@@ -172,7 +177,7 @@ public:
ParentMap &getParentMap();
PseudoConstantAnalysis *getPseudoConstantAnalysis();
- typedef const VarDecl * const * referenced_decls_iterator;
+ using referenced_decls_iterator = const VarDecl * const *;
llvm::iterator_range<referenced_decls_iterator>
getReferencedBlockVars(const BlockDecl *BD);
@@ -200,12 +205,13 @@ public:
if (!data) {
data = T::create(*this);
}
- return static_cast<T*>(data);
+ return static_cast<T *>(data);
}
/// Returns true if the root namespace of the given declaration is the 'std'
/// C++ namespace.
static bool isInStdNamespace(const Decl *D);
+
private:
ManagedAnalysis *&getAnalysisImpl(const void* tag);
@@ -228,7 +234,7 @@ private:
protected:
LocationContext(ContextKind k, AnalysisDeclContext *ctx,
const LocationContext *parent)
- : Kind(k), Ctx(ctx), Parent(parent) {}
+ : Kind(k), Ctx(ctx), Parent(parent) {}
public:
virtual ~LocationContext();
@@ -258,14 +264,18 @@ public:
return Ctx->getSelfDecl();
}
- const StackFrameContext *getCurrentStackFrame() const;
+ const StackFrameContext *getStackFrame() const;
/// Return true if the current LocationContext has no caller context.
virtual bool inTopFrame() const;
virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
- void dumpStack(raw_ostream &OS, StringRef Indent = "") const;
+ void dumpStack(
+ raw_ostream &OS, StringRef Indent = {}, const char *NL = "\n",
+ const char *Sep = "",
+ std::function<void(const LocationContext *)> printMoreInfoPerContext =
+ [](const LocationContext *) {}) const;
void dumpStack() const;
public:
@@ -277,6 +287,8 @@ public:
};
class StackFrameContext : public LocationContext {
+ friend class LocationContextManager;
+
// The callsite where this stack frame is established.
const Stmt *CallSite;
@@ -286,15 +298,14 @@ class StackFrameContext : public LocationContext {
// The index of the callsite in the CFGBlock.
unsigned Index;
- friend class LocationContextManager;
StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent,
const Stmt *s, const CFGBlock *blk,
unsigned idx)
- : LocationContext(StackFrame, ctx, parent), CallSite(s),
- Block(blk), Index(idx) {}
+ : LocationContext(StackFrame, ctx, parent), CallSite(s),
+ Block(blk), Index(idx) {}
public:
- ~StackFrameContext() override {}
+ ~StackFrameContext() override = default;
const Stmt *getCallSite() const { return CallSite; }
@@ -321,15 +332,16 @@ public:
};
class ScopeContext : public LocationContext {
+ friend class LocationContextManager;
+
const Stmt *Enter;
- friend class LocationContextManager;
ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent,
const Stmt *s)
- : LocationContext(Scope, ctx, parent), Enter(s) {}
+ : LocationContext(Scope, ctx, parent), Enter(s) {}
public:
- ~ScopeContext() override {}
+ ~ScopeContext() override = default;
void Profile(llvm::FoldingSetNodeID &ID) override;
@@ -344,20 +356,20 @@ public:
};
class BlockInvocationContext : public LocationContext {
+ friend class LocationContextManager;
+
const BlockDecl *BD;
// FIXME: Come up with a more type-safe way to model context-sensitivity.
const void *ContextData;
- friend class LocationContextManager;
-
BlockInvocationContext(AnalysisDeclContext *ctx,
const LocationContext *parent,
const BlockDecl *bd, const void *contextData)
- : LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {}
+ : LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {}
public:
- ~BlockInvocationContext() override {}
+ ~BlockInvocationContext() override = default;
const BlockDecl *getBlockDecl() const { return BD; }
@@ -379,6 +391,7 @@ public:
class LocationContextManager {
llvm::FoldingSet<LocationContext> Contexts;
+
public:
~LocationContextManager();
@@ -407,8 +420,8 @@ private:
};
class AnalysisDeclContextManager {
- typedef llvm::DenseMap<const Decl *, std::unique_ptr<AnalysisDeclContext>>
- ContextMap;
+ using ContextMap =
+ llvm::DenseMap<const Decl *, std::unique_ptr<AnalysisDeclContext>>;
ContextMap Contexts;
LocationContextManager LocContexts;
@@ -431,10 +444,14 @@ public:
bool addImplicitDtors = false,
bool addInitializers = false,
bool addTemporaryDtors = false,
- bool addLifetime = false, bool addLoopExit = false,
+ bool addLifetime = false,
+ bool addLoopExit = false,
+ bool addScopes = false,
bool synthesizeBodies = false,
bool addStaticInitBranches = false,
bool addCXXNewAllocator = true,
+ bool addRichCXXConstructors = true,
+ bool markElidedCXXConstructors = true,
CodeInjector *injector = nullptr);
AnalysisDeclContext *getContext(const Decl *D);
@@ -488,5 +505,6 @@ private:
}
};
-} // end clang namespace
-#endif
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index cfedb2aa8ed5d..f25789822d162 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -15,8 +15,9 @@
#ifndef LLVM_CLANG_ANALYSIS_CFG_H
#define LLVM_CLANG_ANALYSIS_CFG_H
-#include "clang/AST/Stmt.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/Analysis/Support/BumpVector.h"
+#include "clang/Analysis/ConstructionContext.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
@@ -55,11 +56,18 @@ class CFGElement {
public:
enum Kind {
// main kind
- Statement,
Initializer,
+ ScopeBegin,
+ ScopeEnd,
NewAllocator,
LifetimeEnds,
LoopExit,
+ // stmt kind
+ Statement,
+ Constructor,
+ CXXRecordTypedCall,
+ STMT_BEGIN = Statement,
+ STMT_END = CXXRecordTypedCall,
// dtor kind
AutomaticObjectDtor,
DeleteDtor,
@@ -84,7 +92,7 @@ protected:
CFGElement() = default;
public:
- /// \brief Convert to the specified CFGElement type, asserting that this
+ /// Convert to the specified CFGElement type, asserting that this
/// CFGElement is of the desired type.
template<typename T>
T castAs() const {
@@ -95,7 +103,7 @@ public:
return t;
}
- /// \brief Convert to the specified CFGElement type, returning None if this
+ /// Convert to the specified CFGElement type, returning None if this
/// CFGElement is not of the desired type.
template<typename T>
Optional<T> getAs() const {
@@ -117,7 +125,9 @@ public:
class CFGStmt : public CFGElement {
public:
- CFGStmt(Stmt *S) : CFGElement(Statement, S) {}
+ explicit CFGStmt(Stmt *S, Kind K = Statement) : CFGElement(K, S) {
+ assert(isKind(*this));
+ }
const Stmt *getStmt() const {
return static_cast<const Stmt *>(Data1.getPointer());
@@ -126,10 +136,77 @@ public:
private:
friend class CFGElement;
+ static bool isKind(const CFGElement &E) {
+ return E.getKind() >= STMT_BEGIN && E.getKind() <= STMT_END;
+ }
+
+protected:
CFGStmt() = default;
+};
+
+/// CFGConstructor - Represents C++ constructor call. Maintains information
+/// necessary to figure out what memory is being initialized by the
+/// constructor expression. For now this is only used by the analyzer's CFG.
+class CFGConstructor : public CFGStmt {
+public:
+ explicit CFGConstructor(CXXConstructExpr *CE, const ConstructionContext *C)
+ : CFGStmt(CE, Constructor) {
+ assert(C);
+ Data2.setPointer(const_cast<ConstructionContext *>(C));
+ }
+
+ const ConstructionContext *getConstructionContext() const {
+ return static_cast<ConstructionContext *>(Data2.getPointer());
+ }
+
+private:
+ friend class CFGElement;
+
+ CFGConstructor() = default;
+
+ static bool isKind(const CFGElement &E) {
+ return E.getKind() == Constructor;
+ }
+};
+
+/// CFGCXXRecordTypedCall - Represents a function call that returns a C++ object
+/// by value. This, like constructor, requires a construction context in order
+/// to understand the storage of the returned object . In C such tracking is not
+/// necessary because no additional effort is required for destroying the object
+/// or modeling copy elision. Like CFGConstructor, this element is for now only
+/// used by the analyzer's CFG.
+class CFGCXXRecordTypedCall : public CFGStmt {
+public:
+ /// Returns true when call expression \p CE needs to be represented
+ /// by CFGCXXRecordTypedCall, as opposed to a regular CFGStmt.
+ static bool isCXXRecordTypedCall(CallExpr *CE, const ASTContext &ACtx) {
+ return CE->getCallReturnType(ACtx).getCanonicalType()->getAsCXXRecordDecl();
+ }
+
+ explicit CFGCXXRecordTypedCall(CallExpr *CE, const ConstructionContext *C)
+ : CFGStmt(CE, CXXRecordTypedCall) {
+ // FIXME: This is not protected against squeezing a non-record-typed-call
+ // into the constructor. An assertion would require passing an ASTContext
+ // which would mean paying for something we don't use.
+ assert(C && (isa<TemporaryObjectConstructionContext>(C) ||
+ // These are possible in C++17 due to mandatory copy elision.
+ isa<ReturnedValueConstructionContext>(C) ||
+ isa<VariableConstructionContext>(C) ||
+ isa<ConstructorInitializerConstructionContext>(C)));
+ Data2.setPointer(const_cast<ConstructionContext *>(C));
+ }
+
+ const ConstructionContext *getConstructionContext() const {
+ return static_cast<ConstructionContext *>(Data2.getPointer());
+ }
+
+private:
+ friend class CFGElement;
+
+ CFGCXXRecordTypedCall() = default;
static bool isKind(const CFGElement &E) {
- return E.getKind() == Statement;
+ return E.getKind() == CXXRecordTypedCall;
}
};
@@ -137,7 +214,7 @@ private:
/// constructor's initialization list.
class CFGInitializer : public CFGElement {
public:
- CFGInitializer(CXXCtorInitializer *initializer)
+ explicit CFGInitializer(CXXCtorInitializer *initializer)
: CFGElement(Initializer, initializer) {}
CXXCtorInitializer* getInitializer() const {
@@ -223,6 +300,55 @@ private:
}
};
+/// Represents beginning of a scope implicitly generated
+/// by the compiler on encountering a CompoundStmt
+class CFGScopeBegin : public CFGElement {
+public:
+ CFGScopeBegin() {}
+ CFGScopeBegin(const VarDecl *VD, const Stmt *S)
+ : CFGElement(ScopeBegin, VD, S) {}
+
+ // Get statement that triggered a new scope.
+ const Stmt *getTriggerStmt() const {
+ return static_cast<Stmt*>(Data2.getPointer());
+ }
+
+ // Get VD that triggered a new scope.
+ const VarDecl *getVarDecl() const {
+ return static_cast<VarDecl *>(Data1.getPointer());
+ }
+
+private:
+ friend class CFGElement;
+ static bool isKind(const CFGElement &E) {
+ Kind kind = E.getKind();
+ return kind == ScopeBegin;
+ }
+};
+
+/// Represents end of a scope implicitly generated by
+/// the compiler after the last Stmt in a CompoundStmt's body
+class CFGScopeEnd : public CFGElement {
+public:
+ CFGScopeEnd() {}
+ CFGScopeEnd(const VarDecl *VD, const Stmt *S) : CFGElement(ScopeEnd, VD, S) {}
+
+ const VarDecl *getVarDecl() const {
+ return static_cast<VarDecl *>(Data1.getPointer());
+ }
+
+ const Stmt *getTriggerStmt() const {
+ return static_cast<Stmt *>(Data2.getPointer());
+ }
+
+private:
+ friend class CFGElement;
+ static bool isKind(const CFGElement &E) {
+ Kind kind = E.getKind();
+ return kind == ScopeEnd;
+ }
+};
+
/// CFGImplicitDtor - Represents C++ object destructor implicitly generated
/// by compiler on various occasions.
class CFGImplicitDtor : public CFGElement {
@@ -747,6 +873,17 @@ public:
Elements.push_back(CFGStmt(statement), C);
}
+ void appendConstructor(CXXConstructExpr *CE, const ConstructionContext *CC,
+ BumpVectorContext &C) {
+ Elements.push_back(CFGConstructor(CE, CC), C);
+ }
+
+ void appendCXXRecordTypedCall(CallExpr *CE,
+ const ConstructionContext *CC,
+ BumpVectorContext &C) {
+ Elements.push_back(CFGCXXRecordTypedCall(CE, CC), C);
+ }
+
void appendInitializer(CXXCtorInitializer *initializer,
BumpVectorContext &C) {
Elements.push_back(CFGInitializer(initializer), C);
@@ -757,6 +894,24 @@ public:
Elements.push_back(CFGNewAllocator(NE), C);
}
+ void appendScopeBegin(const VarDecl *VD, const Stmt *S,
+ BumpVectorContext &C) {
+ Elements.push_back(CFGScopeBegin(VD, S), C);
+ }
+
+ void prependScopeBegin(const VarDecl *VD, const Stmt *S,
+ BumpVectorContext &C) {
+ Elements.insert(Elements.rbegin(), 1, CFGScopeBegin(VD, S), C);
+ }
+
+ void appendScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C) {
+ Elements.push_back(CFGScopeEnd(VD, S), C);
+ }
+
+ void prependScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C) {
+ Elements.insert(Elements.rbegin(), 1, CFGScopeEnd(VD, S), C);
+ }
+
void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C) {
Elements.push_back(CFGBaseDtor(BS), C);
}
@@ -810,9 +965,22 @@ public:
*I = CFGLifetimeEnds(VD, S);
return ++I;
}
+
+ // Scope leaving must be performed in reversed order. So insertion is in two
+ // steps. First we prepare space for some number of elements, then we insert
+ // the elements beginning at the last position in prepared space.
+ iterator beginScopeEndInsert(iterator I, size_t Cnt, BumpVectorContext &C) {
+ return iterator(
+ Elements.insert(I.base(), Cnt, CFGScopeEnd(nullptr, nullptr), C));
+ }
+ iterator insertScopeEnd(iterator I, VarDecl *VD, Stmt *S) {
+ *I = CFGScopeEnd(VD, S);
+ return ++I;
+ }
+
};
-/// \brief CFGCallback defines methods that should be called when a logical
+/// CFGCallback defines methods that should be called when a logical
/// operator error is found when building the CFG.
class CFGCallback {
public:
@@ -852,9 +1020,12 @@ public:
bool AddLifetime = false;
bool AddLoopExit = false;
bool AddTemporaryDtors = false;
+ bool AddScopes = false;
bool AddStaticInitBranches = false;
bool AddCXXNewAllocator = false;
bool AddCXXDefaultInitExprInCtors = false;
+ bool AddRichCXXConstructors = false;
+ bool MarkElidedCXXConstructors = false;
BuildOptions() = default;
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h
index bdcdfecddc3eb..ae0f392ed9697 100644
--- a/include/clang/Analysis/CallGraph.h
+++ b/include/clang/Analysis/CallGraph.h
@@ -34,7 +34,7 @@ class Decl;
class DeclContext;
class Stmt;
-/// \brief The AST-based call graph.
+/// The AST-based call graph.
///
/// The call graph extends itself with the given declarations by implementing
/// the recursive AST visitor, which constructs the graph by visiting the given
@@ -55,7 +55,7 @@ public:
CallGraph();
~CallGraph();
- /// \brief Populate the call graph with the functions in the given
+ /// Populate the call graph with the functions in the given
/// declaration.
///
/// Recursively walks the declaration to find all the dependent Decls as well.
@@ -63,13 +63,13 @@ public:
TraverseDecl(D);
}
- /// \brief Determine if a declaration should be included in the graph.
+ /// Determine if a declaration should be included in the graph.
static bool includeInGraph(const Decl *D);
- /// \brief Lookup the node for the given declaration.
+ /// Lookup the node for the given declaration.
CallGraphNode *getNode(const Decl *) const;
- /// \brief Lookup the node for the given declaration. If none found, insert
+ /// Lookup the node for the given declaration. If none found, insert
/// one into the graph.
CallGraphNode *getOrInsertNode(Decl *);
@@ -83,7 +83,7 @@ public:
const_iterator begin() const { return FunctionMap.begin(); }
const_iterator end() const { return FunctionMap.end(); }
- /// \brief Get the number of nodes in the graph.
+ /// Get the number of nodes in the graph.
unsigned size() const { return FunctionMap.size(); }
/// \ brief Get the virtual root of the graph, all the functions available
@@ -133,10 +133,10 @@ public:
bool shouldWalkTypesOfTypeLocs() const { return false; }
private:
- /// \brief Add the given declaration to the call graph.
+ /// Add the given declaration to the call graph.
void addNodeForDecl(Decl *D, bool IsGlobal);
- /// \brief Allocate a new node in the graph.
+ /// Allocate a new node in the graph.
CallGraphNode *allocateNewNode(Decl *);
};
@@ -145,10 +145,10 @@ public:
using CallRecord = CallGraphNode *;
private:
- /// \brief The function/method declaration.
+ /// The function/method declaration.
Decl *FD;
- /// \brief The list of functions called from this node.
+ /// The list of functions called from this node.
SmallVector<CallRecord, 5> CalledFunctions;
public:
diff --git a/include/clang/Analysis/CloneDetection.h b/include/clang/Analysis/CloneDetection.h
index 051b9236658cf..955777a11a652 100644
--- a/include/clang/Analysis/CloneDetection.h
+++ b/include/clang/Analysis/CloneDetection.h
@@ -161,7 +161,7 @@ public:
/// The result of findClones can be further constrained with the constrainClones
/// method.
///
-/// This class only searches for clones in exectuable source code
+/// This class only searches for clones in executable source code
/// (e.g. function bodies). Other clones (e.g. cloned comments or declarations)
/// are not supported.
class CloneDetector {
@@ -351,7 +351,7 @@ struct FilenamePatternConstraint {
/// Analyzes the pattern of the referenced variables in a statement.
class VariablePattern {
- /// Describes an occurence of a variable reference in a statement.
+ /// Describes an occurrence of a variable reference in a statement.
struct VariableOccurence {
/// The index of the associated VarDecl in the Variables vector.
size_t KindID;
@@ -362,7 +362,7 @@ class VariablePattern {
: KindID(KindID), Mention(Mention) {}
};
- /// All occurences of referenced variables in the order of appearance.
+ /// All occurrences of referenced variables in the order of appearance.
std::vector<VariableOccurence> Occurences;
/// List of referenced variables in the order of appearance.
/// Every item in this list is unique.
diff --git a/include/clang/Analysis/CodeInjector.h b/include/clang/Analysis/CodeInjector.h
index 413a55b05b07a..2c87cde996f20 100644
--- a/include/clang/Analysis/CodeInjector.h
+++ b/include/clang/Analysis/CodeInjector.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the clang::CodeInjector interface which is responsible for
+/// Defines the clang::CodeInjector interface which is responsible for
/// injecting AST of function definitions that may not be available in the
/// original source.
///
@@ -23,7 +23,7 @@ class Stmt;
class FunctionDecl;
class ObjCMethodDecl;
-/// \brief CodeInjector is an interface which is responsible for injecting AST
+/// CodeInjector is an interface which is responsible for injecting AST
/// of function definitions that may not be available in the original source.
///
/// The getBody function will be called each time the static analyzer examines a
diff --git a/include/clang/Analysis/ConstructionContext.h b/include/clang/Analysis/ConstructionContext.h
new file mode 100644
index 0000000000000..40cb0e7e5ddaa
--- /dev/null
+++ b/include/clang/Analysis/ConstructionContext.h
@@ -0,0 +1,474 @@
+//===- ConstructionContext.h - CFG constructor information ------*- 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 ConstructionContext class and its sub-classes,
+// which represent various different ways of constructing C++ objects
+// with the additional information the users may want to know about
+// the constructor.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
+#define LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
+
+#include "clang/Analysis/Support/BumpVector.h"
+#include "clang/AST/ExprCXX.h"
+
+namespace clang {
+
+/// Construction context is a linked list of multiple layers. Layers are
+/// created gradually while traversing the AST, and layers that represent
+/// the outmost AST nodes are built first, while the node that immediately
+/// contains the constructor would be built last and capture the previous
+/// layers as its parents. Construction context captures the last layer
+/// (which has links to the previous layers) and classifies the seemingly
+/// arbitrary chain of layers into one of the possible ways of constructing
+/// an object in C++ for user-friendly experience.
+class ConstructionContextLayer {
+public:
+ typedef llvm::PointerUnion<Stmt *, CXXCtorInitializer *> TriggerTy;
+
+private:
+ /// The construction site - the statement that triggered the construction
+ /// for one of its parts. For instance, stack variable declaration statement
+ /// triggers construction of itself or its elements if it's an array,
+ /// new-expression triggers construction of the newly allocated object(s).
+ TriggerTy Trigger;
+
+ /// Sometimes a single trigger is not enough to describe the construction
+ /// site. In this case we'd have a chain of "partial" construction context
+ /// layers.
+ /// Some examples:
+ /// - A constructor within in an aggregate initializer list within a variable
+ /// would have a construction context of the initializer list with
+ /// the parent construction context of a variable.
+ /// - A constructor for a temporary that needs to be both destroyed
+ /// and materialized into an elidable copy constructor would have a
+ /// construction context of a CXXBindTemporaryExpr with the parent
+ /// construction context of a MaterializeTemproraryExpr.
+ /// Not all of these are currently supported.
+ const ConstructionContextLayer *Parent = nullptr;
+
+ ConstructionContextLayer(TriggerTy Trigger,
+ const ConstructionContextLayer *Parent)
+ : Trigger(Trigger), Parent(Parent) {}
+
+public:
+ static const ConstructionContextLayer *
+ create(BumpVectorContext &C, TriggerTy Trigger,
+ const ConstructionContextLayer *Parent = nullptr);
+
+ const ConstructionContextLayer *getParent() const { return Parent; }
+ bool isLast() const { return !Parent; }
+
+ const Stmt *getTriggerStmt() const {
+ return Trigger.dyn_cast<Stmt *>();
+ }
+
+ const CXXCtorInitializer *getTriggerInit() const {
+ return Trigger.dyn_cast<CXXCtorInitializer *>();
+ }
+
+ /// Returns true if these layers are equal as individual layers, even if
+ /// their parents are different.
+ bool isSameLayer(const ConstructionContextLayer *Other) const {
+ assert(Other);
+ return (Trigger == Other->Trigger);
+ }
+
+ /// See if Other is a proper initial segment of this construction context
+ /// in terms of the parent chain - i.e. a few first parents coincide and
+ /// then the other context terminates but our context goes further - i.e.,
+ /// we are providing the same context that the other context provides,
+ /// and a bit more above that.
+ bool isStrictlyMoreSpecificThan(const ConstructionContextLayer *Other) const;
+};
+
+
+/// ConstructionContext's subclasses describe different ways of constructing
+/// an object in C++. The context re-captures the essential parent AST nodes
+/// of the CXXConstructExpr it is assigned to and presents these nodes
+/// through easy-to-understand accessor methods.
+class ConstructionContext {
+public:
+ enum Kind {
+ SimpleVariableKind,
+ CXX17ElidedCopyVariableKind,
+ VARIABLE_BEGIN = SimpleVariableKind,
+ VARIABLE_END = CXX17ElidedCopyVariableKind,
+ SimpleConstructorInitializerKind,
+ CXX17ElidedCopyConstructorInitializerKind,
+ INITIALIZER_BEGIN = SimpleConstructorInitializerKind,
+ INITIALIZER_END = CXX17ElidedCopyConstructorInitializerKind,
+ NewAllocatedObjectKind,
+ SimpleTemporaryObjectKind,
+ ElidedTemporaryObjectKind,
+ TEMPORARY_BEGIN = SimpleTemporaryObjectKind,
+ TEMPORARY_END = ElidedTemporaryObjectKind,
+ SimpleReturnedValueKind,
+ CXX17ElidedCopyReturnedValueKind,
+ RETURNED_VALUE_BEGIN = SimpleReturnedValueKind,
+ RETURNED_VALUE_END = CXX17ElidedCopyReturnedValueKind
+ };
+
+protected:
+ Kind K;
+
+ // Do not make public! These need to only be constructed
+ // via createFromLayers().
+ explicit ConstructionContext(Kind K) : K(K) {}
+
+private:
+ // A helper function for constructing an instance into a bump vector context.
+ template <typename T, typename... ArgTypes>
+ static T *create(BumpVectorContext &C, ArgTypes... Args) {
+ auto *CC = C.getAllocator().Allocate<T>();
+ return new (CC) T(Args...);
+ }
+
+public:
+ /// Consume the construction context layer, together with its parent layers,
+ /// and wrap it up into a complete construction context. May return null
+ /// if layers do not form any supported construction context.
+ static const ConstructionContext *
+ createFromLayers(BumpVectorContext &C,
+ const ConstructionContextLayer *TopLayer);
+
+ Kind getKind() const { return K; }
+};
+
+/// An abstract base class for local variable constructors.
+class VariableConstructionContext : public ConstructionContext {
+ const DeclStmt *DS;
+
+protected:
+ VariableConstructionContext(ConstructionContext::Kind K, const DeclStmt *DS)
+ : ConstructionContext(K), DS(DS) {
+ assert(classof(this));
+ assert(DS);
+ }
+
+public:
+ const DeclStmt *getDeclStmt() const { return DS; }
+
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() >= VARIABLE_BEGIN &&
+ CC->getKind() <= VARIABLE_END;
+ }
+};
+
+/// Represents construction into a simple local variable, eg. T var(123);.
+/// If a variable has an initializer, eg. T var = makeT();, then the final
+/// elidable copy-constructor from makeT() into var would also be a simple
+/// variable constructor handled by this class.
+class SimpleVariableConstructionContext : public VariableConstructionContext {
+ friend class ConstructionContext; // Allows to create<>() itself.
+
+ explicit SimpleVariableConstructionContext(const DeclStmt *DS)
+ : VariableConstructionContext(ConstructionContext::SimpleVariableKind,
+ DS) {}
+
+public:
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() == SimpleVariableKind;
+ }
+};
+
+/// Represents construction into a simple variable with an initializer syntax,
+/// with a single constructor, eg. T var = makeT();. Such construction context
+/// may only appear in C++17 because previously it was split into a temporary
+/// object constructor and an elidable simple variable copy-constructor and
+/// we were producing separate construction contexts for these constructors.
+/// In C++17 we have a single construction context that combines both.
+/// Note that if the object has trivial destructor, then this code is
+/// indistinguishable from a simple variable constructor on the AST level;
+/// in this case we provide a simple variable construction context.
+class CXX17ElidedCopyVariableConstructionContext
+ : public VariableConstructionContext {
+ const CXXBindTemporaryExpr *BTE;
+
+ friend class ConstructionContext; // Allows to create<>() itself.
+
+ explicit CXX17ElidedCopyVariableConstructionContext(
+ const DeclStmt *DS, const CXXBindTemporaryExpr *BTE)
+ : VariableConstructionContext(CXX17ElidedCopyVariableKind, DS), BTE(BTE) {
+ assert(BTE);
+ }
+
+public:
+ const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
+
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() == CXX17ElidedCopyVariableKind;
+ }
+};
+
+// An abstract base class for constructor-initializer-based constructors.
+class ConstructorInitializerConstructionContext : public ConstructionContext {
+ const CXXCtorInitializer *I;
+
+protected:
+ explicit ConstructorInitializerConstructionContext(
+ ConstructionContext::Kind K, const CXXCtorInitializer *I)
+ : ConstructionContext(K), I(I) {
+ assert(classof(this));
+ assert(I);
+ }
+
+public:
+ const CXXCtorInitializer *getCXXCtorInitializer() const { return I; }
+
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() >= INITIALIZER_BEGIN &&
+ CC->getKind() <= INITIALIZER_END;
+ }
+};
+
+/// Represents construction into a field or a base class within a bigger object
+/// via a constructor initializer, eg. T(): field(123) { ... }.
+class SimpleConstructorInitializerConstructionContext
+ : public ConstructorInitializerConstructionContext {
+ friend class ConstructionContext; // Allows to create<>() itself.
+
+ explicit SimpleConstructorInitializerConstructionContext(
+ const CXXCtorInitializer *I)
+ : ConstructorInitializerConstructionContext(
+ ConstructionContext::SimpleConstructorInitializerKind, I) {}
+
+public:
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() == SimpleConstructorInitializerKind;
+ }
+};
+
+/// Represents construction into a field or a base class within a bigger object
+/// via a constructor initializer, with a single constructor, eg.
+/// T(): field(Field(123)) { ... }. Such construction context may only appear
+/// in C++17 because previously it was split into a temporary object constructor
+/// and an elidable simple constructor-initializer copy-constructor and we were
+/// producing separate construction contexts for these constructors. In C++17
+/// we have a single construction context that combines both. Note that if the
+/// object has trivial destructor, then this code is indistinguishable from
+/// a simple constructor-initializer constructor on the AST level; in this case
+/// we provide a simple constructor-initializer construction context.
+class CXX17ElidedCopyConstructorInitializerConstructionContext
+ : public ConstructorInitializerConstructionContext {
+ const CXXBindTemporaryExpr *BTE;
+
+ friend class ConstructionContext; // Allows to create<>() itself.
+
+ explicit CXX17ElidedCopyConstructorInitializerConstructionContext(
+ const CXXCtorInitializer *I, const CXXBindTemporaryExpr *BTE)
+ : ConstructorInitializerConstructionContext(
+ CXX17ElidedCopyConstructorInitializerKind, I),
+ BTE(BTE) {
+ assert(BTE);
+ }
+
+public:
+ const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
+
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() == CXX17ElidedCopyConstructorInitializerKind;
+ }
+};
+
+/// Represents immediate initialization of memory allocated by operator new,
+/// eg. new T(123);.
+class NewAllocatedObjectConstructionContext : public ConstructionContext {
+ const CXXNewExpr *NE;
+
+ friend class ConstructionContext; // Allows to create<>() itself.
+
+ explicit NewAllocatedObjectConstructionContext(const CXXNewExpr *NE)
+ : ConstructionContext(ConstructionContext::NewAllocatedObjectKind),
+ NE(NE) {
+ assert(NE);
+ }
+
+public:
+ const CXXNewExpr *getCXXNewExpr() const { return NE; }
+
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() == NewAllocatedObjectKind;
+ }
+};
+
+/// Represents a temporary object, eg. T(123), that does not immediately cross
+/// function boundaries "by value"; constructors that construct function
+/// value-type arguments or values that are immediately returned from the
+/// function that returns a value receive separate construction context kinds.
+class TemporaryObjectConstructionContext : public ConstructionContext {
+ const CXXBindTemporaryExpr *BTE;
+ const MaterializeTemporaryExpr *MTE;
+
+protected:
+ explicit TemporaryObjectConstructionContext(
+ ConstructionContext::Kind K, const CXXBindTemporaryExpr *BTE,
+ const MaterializeTemporaryExpr *MTE)
+ : ConstructionContext(K), BTE(BTE), MTE(MTE) {
+ // Both BTE and MTE can be null here, all combinations possible.
+ // Even though for now at least one should be non-null, we simply haven't
+ // implemented the other case yet (this would be a temporary in the middle
+ // of nowhere that doesn't have a non-trivial destructor).
+ }
+
+public:
+ /// CXXBindTemporaryExpr here is non-null as long as the temporary has
+ /// a non-trivial destructor.
+ const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const {
+ return BTE;
+ }
+
+ /// MaterializeTemporaryExpr is non-null as long as the temporary is actually
+ /// used after construction, eg. by binding to a reference (lifetime
+ /// extension), accessing a field, calling a method, or passing it into
+ /// a function (an elidable copy or move constructor would be a common
+ /// example) by reference.
+ const MaterializeTemporaryExpr *getMaterializedTemporaryExpr() const {
+ return MTE;
+ }
+
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() >= TEMPORARY_BEGIN && CC->getKind() <= TEMPORARY_END;
+ }
+};
+
+/// Represents a temporary object that is not constructed for the purpose of
+/// being immediately copied/moved by an elidable copy/move-constructor.
+/// This includes temporary objects "in the middle of nowhere" like T(123) and
+/// lifetime-extended temporaries.
+class SimpleTemporaryObjectConstructionContext
+ : public TemporaryObjectConstructionContext {
+ friend class ConstructionContext; // Allows to create<>() itself.
+
+ explicit SimpleTemporaryObjectConstructionContext(
+ const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE)
+ : TemporaryObjectConstructionContext(
+ ConstructionContext::SimpleTemporaryObjectKind, BTE, MTE) {}
+
+public:
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() == SimpleTemporaryObjectKind;
+ }
+};
+
+/// Represents a temporary object that is constructed for the sole purpose
+/// of being immediately copied by an elidable copy/move constructor.
+/// For example, T t = T(123); includes a temporary T(123) that is immediately
+/// copied to variable t. In such cases the elidable copy can (but not
+/// necessarily should) be omitted ("elided") accodring to the rules of the
+/// language; the constructor would then construct variable t directly.
+/// This construction context contains information of the elidable constructor
+/// and its respective construction context.
+class ElidedTemporaryObjectConstructionContext
+ : public TemporaryObjectConstructionContext {
+ const CXXConstructExpr *ElidedCE;
+ const ConstructionContext *ElidedCC;
+
+ friend class ConstructionContext; // Allows to create<>() itself.
+
+ explicit ElidedTemporaryObjectConstructionContext(
+ const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE,
+ const CXXConstructExpr *ElidedCE, const ConstructionContext *ElidedCC)
+ : TemporaryObjectConstructionContext(
+ ConstructionContext::ElidedTemporaryObjectKind, BTE, MTE),
+ ElidedCE(ElidedCE), ElidedCC(ElidedCC) {
+ // Elided constructor and its context should be either both specified
+ // or both unspecified. In the former case, the constructor must be
+ // elidable.
+ assert(ElidedCE && ElidedCE->isElidable() && ElidedCC);
+ }
+
+public:
+ const CXXConstructExpr *getConstructorAfterElision() const {
+ return ElidedCE;
+ }
+
+ const ConstructionContext *getConstructionContextAfterElision() const {
+ return ElidedCC;
+ }
+
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() == ElidedTemporaryObjectKind;
+ }
+};
+
+class ReturnedValueConstructionContext : public ConstructionContext {
+ const ReturnStmt *RS;
+
+protected:
+ explicit ReturnedValueConstructionContext(ConstructionContext::Kind K,
+ const ReturnStmt *RS)
+ : ConstructionContext(K), RS(RS) {
+ assert(classof(this));
+ assert(RS);
+ }
+
+public:
+ const ReturnStmt *getReturnStmt() const { return RS; }
+
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() >= RETURNED_VALUE_BEGIN &&
+ CC->getKind() <= RETURNED_VALUE_END;
+ }
+};
+
+/// Represents a temporary object that is being immediately returned from a
+/// function by value, eg. return t; or return T(123);. In this case there is
+/// always going to be a constructor at the return site. However, the usual
+/// temporary-related bureaucracy (CXXBindTemporaryExpr,
+/// MaterializeTemporaryExpr) is normally located in the caller function's AST.
+class SimpleReturnedValueConstructionContext
+ : public ReturnedValueConstructionContext {
+ friend class ConstructionContext; // Allows to create<>() itself.
+
+ explicit SimpleReturnedValueConstructionContext(const ReturnStmt *RS)
+ : ReturnedValueConstructionContext(
+ ConstructionContext::SimpleReturnedValueKind, RS) {}
+
+public:
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() == SimpleReturnedValueKind;
+ }
+};
+
+/// Represents a temporary object that is being immediately returned from a
+/// function by value, eg. return t; or return T(123); in C++17.
+/// In C++17 there is not going to be an elidable copy constructor at the
+/// return site. However, the usual temporary-related bureaucracy (CXXBindTemporaryExpr,
+/// MaterializeTemporaryExpr) is normally located in the caller function's AST.
+/// Note that if the object has trivial destructor, then this code is
+/// indistinguishable from a simple returned value constructor on the AST level;
+/// in this case we provide a simple returned value construction context.
+class CXX17ElidedCopyReturnedValueConstructionContext
+ : public ReturnedValueConstructionContext {
+ const CXXBindTemporaryExpr *BTE;
+
+ friend class ConstructionContext; // Allows to create<>() itself.
+
+ explicit CXX17ElidedCopyReturnedValueConstructionContext(
+ const ReturnStmt *RS, const CXXBindTemporaryExpr *BTE)
+ : ReturnedValueConstructionContext(
+ ConstructionContext::CXX17ElidedCopyReturnedValueKind, RS),
+ BTE(BTE) {
+ assert(BTE);
+ }
+
+public:
+ const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
+
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() == CXX17ElidedCopyReturnedValueKind;
+ }
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 2d59dec48a880..e8f0d61617eb7 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -73,8 +73,9 @@ public:
PostStoreKind,
PostConditionKind,
PostLValueKind,
+ PostAllocatorCallKind,
MinPostStmtKind = PostStmtKind,
- MaxPostStmtKind = PostLValueKind,
+ MaxPostStmtKind = PostAllocatorCallKind,
PostInitializerKind,
CallEnterKind,
CallExitBeginKind,
@@ -97,7 +98,7 @@ private:
llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;
protected:
- ProgramPoint() {}
+ ProgramPoint() = default;
ProgramPoint(const void *P,
Kind k,
const LocationContext *l,
@@ -134,7 +135,7 @@ public:
getLocationContext(), tag);
}
- /// \brief Convert to the specified ProgramPoint type, asserting that this
+ /// Convert to the specified ProgramPoint type, asserting that this
/// ProgramPoint is of the desired type.
template<typename T>
T castAs() const {
@@ -145,7 +146,7 @@ public:
return t;
}
- /// \brief Convert to the specified ProgramPoint type, returning None if this
+ /// Convert to the specified ProgramPoint type, returning None if this
/// ProgramPoint is not of the desired type.
template<typename T>
Optional<T> getAs() const {
@@ -166,7 +167,7 @@ public:
return (Kind) x;
}
- /// \brief Is this a program point corresponding to purge/removal of dead
+ /// Is this a program point corresponding to purge/removal of dead
/// symbols and bindings.
bool isPurgeKind() {
Kind K = getKind();
@@ -180,6 +181,10 @@ public:
return L.getPointer();
}
+ const StackFrameContext *getStackFrame() const {
+ return getLocationContext()->getStackFrame();
+ }
+
// For use with DenseMap. This hash is probably slow.
unsigned getHashValue() const {
llvm::FoldingSetNodeID ID;
@@ -233,7 +238,7 @@ public:
private:
friend class ProgramPoint;
- BlockEntrance() {}
+ BlockEntrance() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == BlockEntranceKind;
}
@@ -254,7 +259,7 @@ public:
private:
friend class ProgramPoint;
- BlockExit() {}
+ BlockExit() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == BlockExitKind;
}
@@ -274,7 +279,7 @@ public:
const T* getStmtAs() const { return dyn_cast<T>(getStmt()); }
protected:
- StmtPoint() {}
+ StmtPoint() = default;
private:
friend class ProgramPoint;
static bool isKind(const ProgramPoint &Location) {
@@ -294,7 +299,7 @@ public:
private:
friend class ProgramPoint;
- PreStmt() {}
+ PreStmt() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == PreStmtKind;
}
@@ -302,7 +307,7 @@ private:
class PostStmt : public StmtPoint {
protected:
- PostStmt() {}
+ PostStmt() = default;
PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L,
const ProgramPointTag *tag = nullptr)
: StmtPoint(S, data, k, L, tag) {}
@@ -333,7 +338,7 @@ public:
private:
friend class ProgramPoint;
- PostCondition() {}
+ PostCondition() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == PostConditionKind;
}
@@ -341,7 +346,7 @@ private:
class LocationCheck : public StmtPoint {
protected:
- LocationCheck() {}
+ LocationCheck() = default;
LocationCheck(const Stmt *S, const LocationContext *L,
ProgramPoint::Kind K, const ProgramPointTag *tag)
: StmtPoint(S, nullptr, K, L, tag) {}
@@ -362,7 +367,7 @@ public:
private:
friend class ProgramPoint;
- PreLoad() {}
+ PreLoad() = default;
static bool isKind(const ProgramPoint &location) {
return location.getKind() == PreLoadKind;
}
@@ -376,7 +381,7 @@ public:
private:
friend class ProgramPoint;
- PreStore() {}
+ PreStore() = default;
static bool isKind(const ProgramPoint &location) {
return location.getKind() == PreStoreKind;
}
@@ -390,13 +395,13 @@ public:
private:
friend class ProgramPoint;
- PostLoad() {}
+ PostLoad() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == PostLoadKind;
}
};
-/// \brief Represents a program point after a store evaluation.
+/// Represents a program point after a store evaluation.
class PostStore : public PostStmt {
public:
/// Construct the post store point.
@@ -409,7 +414,7 @@ public:
setData2(Loc);
}
- /// \brief Returns the information about the location used in the store,
+ /// Returns the information about the location used in the store,
/// how it was uttered in the code.
const void *getLocationValue() const {
return getData2();
@@ -417,7 +422,7 @@ public:
private:
friend class ProgramPoint;
- PostStore() {}
+ PostStore() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == PostStoreKind;
}
@@ -431,7 +436,7 @@ public:
private:
friend class ProgramPoint;
- PostLValue() {}
+ PostLValue() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == PostLValueKind;
}
@@ -447,7 +452,7 @@ public:
private:
friend class ProgramPoint;
- PreStmtPurgeDeadSymbols() {}
+ PreStmtPurgeDeadSymbols() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == PreStmtPurgeDeadSymbolsKind;
}
@@ -463,7 +468,7 @@ public:
private:
friend class ProgramPoint;
- PostStmtPurgeDeadSymbols() {}
+ PostStmtPurgeDeadSymbols() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == PostStmtPurgeDeadSymbolsKind;
}
@@ -487,7 +492,7 @@ public:
private:
friend class ProgramPoint;
- BlockEdge() {}
+ BlockEdge() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == BlockEdgeKind;
}
@@ -495,7 +500,7 @@ private:
class PostInitializer : public ProgramPoint {
public:
- /// \brief Construct a PostInitializer point that represents a location after
+ /// Construct a PostInitializer point that represents a location after
/// CXXCtorInitializer expression evaluation.
///
/// \param I The initializer.
@@ -509,14 +514,14 @@ public:
return static_cast<const CXXCtorInitializer *>(getData1());
}
- /// \brief Returns the location of the field.
+ /// Returns the location of the field.
const void *getLocationValue() const {
return getData2();
}
private:
friend class ProgramPoint;
- PostInitializer() {}
+ PostInitializer() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == PostInitializerKind;
}
@@ -537,7 +542,7 @@ public:
}
protected:
- ImplicitCallPoint() {}
+ ImplicitCallPoint() = default;
private:
friend class ProgramPoint;
static bool isKind(const ProgramPoint &Location) {
@@ -557,7 +562,7 @@ public:
private:
friend class ProgramPoint;
- PreImplicitCall() {}
+ PreImplicitCall() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == PreImplicitCallKind;
}
@@ -574,12 +579,26 @@ public:
private:
friend class ProgramPoint;
- PostImplicitCall() {}
+ PostImplicitCall() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == PostImplicitCallKind;
}
};
+class PostAllocatorCall : public StmtPoint {
+public:
+ PostAllocatorCall(const Stmt *S, const LocationContext *L,
+ const ProgramPointTag *Tag = nullptr)
+ : StmtPoint(S, nullptr, PostAllocatorCallKind, L, Tag) {}
+
+private:
+ friend class ProgramPoint;
+ PostAllocatorCall() = default;
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == PostAllocatorCallKind;
+ }
+};
+
/// Represents a point when we begin processing an inlined call.
/// CallEnter uses the caller's location context.
class CallEnter : public ProgramPoint {
@@ -605,7 +624,7 @@ public:
private:
friend class ProgramPoint;
- CallEnter() {}
+ CallEnter() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == CallEnterKind;
}
@@ -626,9 +645,13 @@ public:
CallExitBegin(const StackFrameContext *L, const ReturnStmt *RS)
: ProgramPoint(RS, CallExitBeginKind, L, nullptr) { }
+ const ReturnStmt *getReturnStmt() const {
+ return static_cast<const ReturnStmt *>(getData1());
+ }
+
private:
friend class ProgramPoint;
- CallExitBegin() {}
+ CallExitBegin() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == CallExitBeginKind;
}
@@ -649,7 +672,7 @@ public:
private:
friend class ProgramPoint;
- CallExitEnd() {}
+ CallExitEnd() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == CallExitEndKind;
}
@@ -672,7 +695,7 @@ public:
private:
friend class ProgramPoint;
- LoopExit() {}
+ LoopExit() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == LoopExitKind;
}
@@ -691,7 +714,7 @@ public:
private:
friend class ProgramPoint;
- EpsilonPoint() {}
+ EpsilonPoint() = default;
static bool isKind(const ProgramPoint &Location) {
return Location.getKind() == EpsilonKind;
}
diff --git a/include/clang/Basic/ABI.h b/include/clang/Basic/ABI.h
index 75e9faf4617e2..bd919ce24f81f 100644
--- a/include/clang/Basic/ABI.h
+++ b/include/clang/Basic/ABI.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Enums/classes describing ABI related information about constructors,
+/// Enums/classes describing ABI related information about constructors,
/// destructors and thunks.
///
//===----------------------------------------------------------------------===//
@@ -21,7 +21,7 @@
namespace clang {
-/// \brief C++ constructor types.
+/// C++ constructor types.
enum CXXCtorType {
Ctor_Complete, ///< Complete object ctor
Ctor_Base, ///< Base object ctor
@@ -30,7 +30,7 @@ enum CXXCtorType {
Ctor_DefaultClosure, ///< Default closure variant of a ctor
};
-/// \brief C++ destructor types.
+/// C++ destructor types.
enum CXXDtorType {
Dtor_Deleting, ///< Deleting dtor
Dtor_Complete, ///< Complete object dtor
@@ -38,29 +38,29 @@ enum CXXDtorType {
Dtor_Comdat ///< The COMDAT used for dtors
};
-/// \brief A return adjustment.
+/// A return adjustment.
struct ReturnAdjustment {
- /// \brief The non-virtual adjustment from the derived object to its
+ /// The non-virtual adjustment from the derived object to its
/// nearest virtual base.
int64_t NonVirtual;
- /// \brief Holds the ABI-specific information about the virtual return
+ /// Holds the ABI-specific information about the virtual return
/// adjustment, if needed.
union VirtualAdjustment {
// Itanium ABI
struct {
- /// \brief The offset (in bytes), relative to the address point
+ /// The offset (in bytes), relative to the address point
/// of the virtual base class offset.
int64_t VBaseOffsetOffset;
} Itanium;
// Microsoft ABI
struct {
- /// \brief The offset (in bytes) of the vbptr, relative to the beginning
+ /// The offset (in bytes) of the vbptr, relative to the beginning
/// of the derived class.
uint32_t VBPtrOffset;
- /// \brief Index of the virtual base in the vbtable.
+ /// Index of the virtual base in the vbtable.
uint32_t VBIndex;
} Microsoft;
@@ -104,31 +104,31 @@ struct ReturnAdjustment {
}
};
-/// \brief A \c this pointer adjustment.
+/// A \c this pointer adjustment.
struct ThisAdjustment {
- /// \brief The non-virtual adjustment from the derived object to its
+ /// The non-virtual adjustment from the derived object to its
/// nearest virtual base.
int64_t NonVirtual;
- /// \brief Holds the ABI-specific information about the virtual this
+ /// Holds the ABI-specific information about the virtual this
/// adjustment, if needed.
union VirtualAdjustment {
// Itanium ABI
struct {
- /// \brief The offset (in bytes), relative to the address point,
+ /// The offset (in bytes), relative to the address point,
/// of the virtual call offset.
int64_t VCallOffsetOffset;
} Itanium;
struct {
- /// \brief The offset of the vtordisp (in bytes), relative to the ECX.
+ /// The offset of the vtordisp (in bytes), relative to the ECX.
int32_t VtordispOffset;
- /// \brief The offset of the vbptr of the derived class (in bytes),
+ /// The offset of the vbptr of the derived class (in bytes),
/// relative to the ECX after vtordisp adjustment.
int32_t VBPtrOffset;
- /// \brief The offset (in bytes) of the vbase offset in the vbtable.
+ /// The offset (in bytes) of the vbase offset in the vbtable.
int32_t VBOffsetOffset;
} Microsoft;
@@ -174,16 +174,16 @@ struct ThisAdjustment {
class CXXMethodDecl;
-/// \brief The \c this pointer adjustment as well as an optional return
+/// The \c this pointer adjustment as well as an optional return
/// adjustment for a thunk.
struct ThunkInfo {
- /// \brief The \c this pointer adjustment.
+ /// The \c this pointer adjustment.
ThisAdjustment This;
- /// \brief The return adjustment.
+ /// The return adjustment.
ReturnAdjustment Return;
- /// \brief Holds a pointer to the overridden method this thunk is for,
+ /// Holds a pointer to the overridden method this thunk is for,
/// if needed by the ABI to distinguish different thunks with equal
/// adjustments. Otherwise, null.
/// CAUTION: In the unlikely event you need to sort ThunkInfos, consider using
diff --git a/include/clang/Basic/AddressSpaces.h b/include/clang/Basic/AddressSpaces.h
index 6b0090813e9b4..217fbd763ff2e 100644
--- a/include/clang/Basic/AddressSpaces.h
+++ b/include/clang/Basic/AddressSpaces.h
@@ -1,4 +1,4 @@
-//===--- AddressSpaces.h - Language-specific address spaces -----*- C++ -*-===//
+//===- AddressSpaces.h - Language-specific address spaces -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,25 +6,25 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
-/// \brief Provides definitions for the various language-specific address
+/// Provides definitions for the various language-specific address
/// spaces.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_ADDRESSSPACES_H
#define LLVM_CLANG_BASIC_ADDRESSSPACES_H
-#include <assert.h>
+#include <cassert>
namespace clang {
-/// \brief Defines the address space values used by the address space qualifier
+/// Defines the address space values used by the address space qualifier
/// of QualType.
///
enum class LangAS : unsigned {
- // The default value 0 is the value used in QualType for the the situation
+ // The default value 0 is the value used in QualType for the situation
// where there is no address space qualifier.
Default = 0,
@@ -51,7 +51,7 @@ enum class LangAS : unsigned {
/// The type of a lookup table which maps from language-specific address spaces
/// to target-specific ones.
-typedef unsigned LangASMap[(unsigned)LangAS::FirstTargetAddressSpace];
+using LangASMap = unsigned[(unsigned)LangAS::FirstTargetAddressSpace];
/// \return whether \p AS is a target-specific address space rather than a
/// clang AST address space
@@ -71,4 +71,4 @@ inline LangAS getLangASFromTargetAS(unsigned TargetAS) {
} // namespace clang
-#endif
+#endif // LLVM_CLANG_BASIC_ADDRESSSPACES_H
diff --git a/include/clang/Basic/AlignedAllocation.h b/include/clang/Basic/AlignedAllocation.h
index b3496949f39ac..9751f41184477 100644
--- a/include/clang/Basic/AlignedAllocation.h
+++ b/include/clang/Basic/AlignedAllocation.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines a function that returns the minimum OS versions supporting
+/// Defines a function that returns the minimum OS versions supporting
/// C++17's aligned allocation functions.
///
//===----------------------------------------------------------------------===//
@@ -16,24 +16,24 @@
#ifndef LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
#define LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
-#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/VersionTuple.h"
namespace clang {
-inline VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS) {
+inline llvm::VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS) {
switch (OS) {
default:
break;
case llvm::Triple::Darwin:
case llvm::Triple::MacOSX: // Earliest supporting version is 10.13.
- return VersionTuple(10U, 13U);
+ return llvm::VersionTuple(10U, 13U);
case llvm::Triple::IOS:
case llvm::Triple::TvOS: // Earliest supporting version is 11.0.0.
- return VersionTuple(11U);
+ return llvm::VersionTuple(11U);
case llvm::Triple::WatchOS: // Earliest supporting version is 4.0.0.
- return VersionTuple(4U);
+ return llvm::VersionTuple(4U);
}
llvm_unreachable("Unexpected OS");
diff --git a/include/clang/Basic/AllDiagnostics.h b/include/clang/Basic/AllDiagnostics.h
index 1c83e2d0f8a0b..20c29d459d229 100644
--- a/include/clang/Basic/AllDiagnostics.h
+++ b/include/clang/Basic/AllDiagnostics.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Includes all the separate Diagnostic headers & some related helpers.
+/// Includes all the separate Diagnostic headers & some related helpers.
///
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 8b84c4b8b50de..0bbe52bf5f36f 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -83,6 +83,9 @@ def LocalVar : SubsetSubject<Var,
def NonParmVar : SubsetSubject<Var,
[{S->getKind() != Decl::ParmVar}],
"variables">;
+def NonLocalVar : SubsetSubject<Var,
+ [{!S->hasLocalStorage()}],
+ "variables with non-local storage">;
def NonBitField : SubsetSubject<Field,
[{!S->isBitField()}],
"non-bit-field non-static data members">;
@@ -111,6 +114,9 @@ def SharedVar : SubsetSubject<Var,
def GlobalVar : SubsetSubject<Var,
[{S->hasGlobalStorage()}], "global variables">;
+def InlineFunction : SubsetSubject<Function,
+ [{S->isInlineSpecified()}], "inline functions">;
+
// FIXME: this hack is needed because DeclNodes.td defines the base Decl node
// type to be a class, not a definition. This makes it impossible to create an
// attribute subject which accepts a Decl. Normally, this is not a problem,
@@ -162,6 +168,13 @@ class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>;
class VariadicUnsignedArgument<string name> : Argument<name, 1>;
class VariadicExprArgument<string name> : Argument<name, 1>;
class VariadicStringArgument<string name> : Argument<name, 1>;
+class VariadicIdentifierArgument<string name> : Argument<name, 1>;
+
+// Like VariadicUnsignedArgument except values are ParamIdx.
+class VariadicParamIdxArgument<string name> : Argument<name, 1>;
+
+// Like VariadicParamIdxArgument but for a single function parameter index.
+class ParamIdxArgument<string name, bit opt = 0> : Argument<name, opt>;
// A version of the form major.minor[.subminor].
class VersionArgument<string name, bit opt = 0> : Argument<name, opt>;
@@ -172,7 +185,8 @@ class VersionArgument<string name, bit opt = 0> : Argument<name, opt>;
class AlignedArgument<string name, bit opt = 0> : Argument<name, opt>;
// A bool argument with a default value
-class DefaultBoolArgument<string name, bit default> : BoolArgument<name, 1> {
+class DefaultBoolArgument<string name, bit default, bit fake = 0>
+ : BoolArgument<name, 1, fake> {
bit Default = default;
}
@@ -231,9 +245,12 @@ class GCC<string name> : Spelling<name, "GCC"> {
let KnownToGCC = 1;
}
-// The Clang spelling implies GNU<name> and CXX11<"clang", name>. This spelling
-// should be used for any Clang-specific attributes.
-class Clang<string name> : Spelling<name, "Clang">;
+// The Clang spelling implies GNU<name>, CXX11<"clang", name>, and optionally,
+// C2x<"clang", name>. This spelling should be used for any Clang-specific
+// attributes.
+class Clang<string name, bit allowInC = 1> : Spelling<name, "Clang"> {
+ bit AllowInC = allowInC;
+}
class Accessor<string name, list<Spelling> spellings> {
string Name = name;
@@ -291,6 +308,7 @@ def TargetAVR : TargetArch<["avr"]>;
def TargetMips32 : TargetArch<["mips", "mipsel"]>;
def TargetAnyMips : TargetArch<["mips", "mipsel", "mips64", "mips64el"]>;
def TargetMSP430 : TargetArch<["msp430"]>;
+def TargetRISCV : TargetArch<["riscv32", "riscv64"]>;
def TargetX86 : TargetArch<["x86"]>;
def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> {
@@ -438,9 +456,6 @@ class Attr {
// Set to true if all of the attribute's arguments should be parsed in an
// unevaluated context.
bit ParseArgumentsAsUnevaluated = 0;
- // Set to true if this attribute can be duplicated on a subject when merging
- // attributes. By default, attributes are not merged.
- bit DuplicatesAllowedWhileMerging = 0;
// Set to true if this attribute meaningful when applied to or inherited
// in a class template definition.
bit MeaningfulToClassTemplateDefinition = 0;
@@ -475,7 +490,16 @@ class TypeAttr : Attr {
class StmtAttr : Attr;
/// An inheritable attribute is inherited by later redeclarations.
-class InheritableAttr : Attr;
+class InheritableAttr : Attr {
+ // Set to true if this attribute can be duplicated on a subject when inheriting
+ // attributes from prior declarations.
+ bit InheritEvenIfAlreadyPresent = 0;
+}
+
+/// Some attributes, like calling conventions, can appear in either the
+/// declaration or the type position. These attributes are morally type
+/// attributes, but have historically been written on declarations.
+class DeclOrTypeAttr : InheritableAttr;
/// A target-specific attribute. This class is meant to be used as a mixin
/// with InheritableAttr or Attr depending on the attribute's needs.
@@ -487,7 +511,7 @@ class TargetSpecificAttr<TargetSpec target> {
// "exists" for a given target. So two target-specific attributes can share
// the same name when they exist in different targets. To support this, a
// Kind can be explicitly specified for a target-specific attribute. This
- // corresponds to the AttributeList::AT_* enum that is generated and it
+ // corresponds to the ParsedAttr::AT_* enum that is generated and it
// should contain a shared value between the attributes.
//
// Target-specific attributes which use this feature should ensure that the
@@ -584,6 +608,12 @@ def AlwaysInline : InheritableAttr {
let Documentation = [Undocumented];
}
+def Artificial : InheritableAttr {
+ let Spellings = [GCC<"artificial">];
+ let Subjects = SubjectList<[InlineFunction], WarnDiag>;
+ let Documentation = [ArtificialDocs];
+}
+
def XRayInstrument : InheritableAttr {
let Spellings = [Clang<"xray_always_instrument">,
Clang<"xray_never_instrument">];
@@ -598,6 +628,12 @@ def XRayInstrument : InheritableAttr {
def XRayLogArgs : InheritableAttr {
let Spellings = [Clang<"xray_log_args">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
+ // This argument is a count not an index, so it has the same encoding (base
+ // 1 including C++ implicit this parameter) at the source and LLVM levels of
+ // representation, so ParamIdxArgument is inappropriate. It is never used
+ // at the AST level of representation, so it never needs to be adjusted not
+ // to include any C++ implicit this parameter. Thus, we just store it and
+ // use it as an unsigned that never needs adjustment.
let Args = [UnsignedArgument<"ArgumentCount">];
let Documentation = [XRayDocs];
}
@@ -660,9 +696,7 @@ def AsmLabel : InheritableAttr {
}
def Availability : InheritableAttr {
- // TODO: does not have a [[]] spelling because it requires custom parsing
- // support.
- let Spellings = [GNU<"availability">];
+ let Spellings = [Clang<"availability">];
let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">,
VersionArgument<"deprecated">, VersionArgument<"obsoleted">,
BoolArgument<"unavailable">, StringArgument<"message">,
@@ -706,7 +740,7 @@ static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
.Default(Platform);
} }];
let HasCustomParsing = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Subjects = SubjectList<[Named]>;
let Documentation = [AvailabilityDocs];
}
@@ -739,7 +773,7 @@ def CarriesDependency : InheritableParamAttr {
let Documentation = [CarriesDependencyDocs];
}
-def CDecl : InheritableAttr {
+def CDecl : DeclOrTypeAttr {
let Spellings = [GCC<"cdecl">, Keyword<"__cdecl">, Keyword<"_cdecl">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [Undocumented];
@@ -813,6 +847,27 @@ def Constructor : InheritableAttr {
let Documentation = [Undocumented];
}
+def CPUSpecific : InheritableAttr {
+ let Spellings = [Clang<"cpu_specific">];
+ let Args = [VariadicIdentifierArgument<"Cpus">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [CPUSpecificCPUDispatchDocs];
+ let AdditionalMembers = [{
+ unsigned ActiveArgIndex = 0;
+
+ IdentifierInfo *getCurCPUName() const {
+ return *(cpus_begin() + ActiveArgIndex);
+ }
+ }];
+}
+
+def CPUDispatch : InheritableAttr {
+ let Spellings = [Clang<"cpu_dispatch">];
+ let Args = [VariadicIdentifierArgument<"Cpus">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [CPUSpecificCPUDispatchDocs];
+}
+
// CUDA attributes are spelled __attribute__((attr)) or __declspec(__attr__),
// and they do not receive a [[]] spelling.
def CUDAConstant : InheritableAttr {
@@ -1007,7 +1062,8 @@ def EmptyBases : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
def AllocSize : InheritableAttr {
let Spellings = [GCC<"alloc_size">];
let Subjects = SubjectList<[Function]>;
- let Args = [IntArgument<"ElemSizeParam">, IntArgument<"NumElemsParam", 1>];
+ let Args = [ParamIdxArgument<"ElemSizeParam">,
+ ParamIdxArgument<"NumElemsParam", /*opt*/ 1>];
let TemplateDependent = 1;
let Documentation = [AllocSizeDocs];
}
@@ -1039,14 +1095,14 @@ def FallThrough : StmtAttr {
let Documentation = [FallthroughDocs];
}
-def FastCall : InheritableAttr {
+def FastCall : DeclOrTypeAttr {
let Spellings = [GCC<"fastcall">, Keyword<"__fastcall">,
Keyword<"_fastcall">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [FastCallDocs];
}
-def RegCall : InheritableAttr {
+def RegCall : DeclOrTypeAttr {
let Spellings = [GCC<"regcall">, Keyword<"__regcall">];
let Documentation = [RegCallDocs];
}
@@ -1094,7 +1150,7 @@ def Format : InheritableAttr {
def FormatArg : InheritableAttr {
let Spellings = [GCC<"format_arg">];
- let Args = [IntArgument<"FormatIdx">];
+ let Args = [ParamIdxArgument<"FormatIdx">];
let Subjects = SubjectList<[ObjCMethod, HasFunctionProto]>;
let Documentation = [Undocumented];
}
@@ -1155,6 +1211,15 @@ def LayoutVersion : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
let Documentation = [LayoutVersionDocs];
}
+def TrivialABI : InheritableAttr {
+ // This attribute does not have a C [[]] spelling because it requires the
+ // CPlusPlus language option.
+ let Spellings = [Clang<"trivial_abi", 0>];
+ let Subjects = SubjectList<[CXXRecord]>;
+ let Documentation = [TrivialABIDocs];
+ let LangOpts = [CPlusPlus];
+}
+
def MaxFieldAlignment : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
@@ -1169,7 +1234,7 @@ def MayAlias : InheritableAttr {
let Documentation = [Undocumented];
}
-def MSABI : InheritableAttr {
+def MSABI : DeclOrTypeAttr {
let Spellings = [GCC<"ms_abi">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [MSABIDocs];
@@ -1310,6 +1375,17 @@ def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips32> {
let Documentation = [MicroMipsDocs];
}
+def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> {
+ let Spellings = [GCC<"interrupt">];
+ let Subjects = SubjectList<[Function]>;
+ let Args = [EnumArgument<"Interrupt", "InterruptType",
+ ["user", "supervisor", "machine"],
+ ["user", "supervisor", "machine"],
+ 1>];
+ let ParseKind = "Interrupt";
+ let Documentation = [RISCVInterruptDocs];
+}
+
// This is not a TargetSpecificAttr so that is silently accepted and
// ignored on other targets as encouraged by the OpenCL spec.
//
@@ -1328,28 +1404,28 @@ def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips32> {
// this should be rejected on non-kernels.
def AMDGPUFlatWorkGroupSize : InheritableAttr {
- let Spellings = [Clang<"amdgpu_flat_work_group_size">];
+ let Spellings = [Clang<"amdgpu_flat_work_group_size", 0>];
let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max">];
let Documentation = [AMDGPUFlatWorkGroupSizeDocs];
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}
def AMDGPUWavesPerEU : InheritableAttr {
- let Spellings = [Clang<"amdgpu_waves_per_eu">];
+ let Spellings = [Clang<"amdgpu_waves_per_eu", 0>];
let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max", 1>];
let Documentation = [AMDGPUWavesPerEUDocs];
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}
def AMDGPUNumSGPR : InheritableAttr {
- let Spellings = [Clang<"amdgpu_num_sgpr">];
+ let Spellings = [Clang<"amdgpu_num_sgpr", 0>];
let Args = [UnsignedArgument<"NumSGPR">];
let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}
def AMDGPUNumVGPR : InheritableAttr {
- let Spellings = [Clang<"amdgpu_num_vgpr">];
+ let Spellings = [Clang<"amdgpu_num_vgpr", 0>];
let Args = [UnsignedArgument<"NumVGPR">];
let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
@@ -1365,18 +1441,18 @@ def NonNull : InheritableParamAttr {
let Spellings = [GCC<"nonnull">];
let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag,
"functions, methods, and parameters">;
- let Args = [VariadicUnsignedArgument<"Args">];
- let AdditionalMembers =
-[{bool isNonNull(unsigned idx) const {
- if (!args_size())
- return true;
- for (const auto &V : args())
- if (V == idx)
+ let Args = [VariadicParamIdxArgument<"Args">];
+ let AdditionalMembers = [{
+ bool isNonNull(unsigned IdxAST) const {
+ if (!args_size())
return true;
- return false;
- } }];
+ return args_end() != std::find_if(
+ args_begin(), args_end(),
+ [=](const ParamIdx &Idx) { return Idx.getASTIndex() == IdxAST; });
+ }
+ }];
// FIXME: We should merge duplicates into a single nonnull attribute.
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Documentation = [NonNullDocs];
}
@@ -1432,7 +1508,7 @@ def AssumeAligned : InheritableAttr {
def AllocAlign : InheritableAttr {
let Spellings = [GCC<"alloc_align">];
let Subjects = SubjectList<[HasFunctionProto]>;
- let Args = [IntArgument<"ParamIndex">];
+ let Args = [ParamIdxArgument<"ParamIndex">];
let Documentation = [AllocAlignDocs];
}
@@ -1454,6 +1530,12 @@ def NotTailCalled : InheritableAttr {
let Documentation = [NotTailCalledDocs];
}
+def NoStackProtector : InheritableAttr {
+ let Spellings = [Clang<"no_stack_protector">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [NoStackProtectorDocs];
+}
+
def NoThrow : InheritableAttr {
let Spellings = [GCC<"nothrow">, Declspec<"nothrow">];
let Subjects = SubjectList<[Function]>;
@@ -1483,13 +1565,11 @@ def ObjCBridgeMutable : InheritableAttr {
}
def ObjCBridgeRelated : InheritableAttr {
- // TODO: this attribute does not have a [[]] spelling because it requires
- // custom parsing support.
- let Spellings = [GNU<"objc_bridge_related">];
+ let Spellings = [Clang<"objc_bridge_related">];
let Subjects = SubjectList<[Record], ErrorDiag>;
let Args = [IdentifierArgument<"RelatedClass">,
- IdentifierArgument<"ClassMethod", 1>,
- IdentifierArgument<"InstanceMethod", 1>];
+ IdentifierArgument<"ClassMethod">,
+ IdentifierArgument<"InstanceMethod">];
let HasCustomParsing = 1;
let Documentation = [Undocumented];
}
@@ -1643,7 +1723,8 @@ def Ownership : InheritableAttr {
Returns;
}
}];
- let Args = [IdentifierArgument<"Module">, VariadicUnsignedArgument<"Args">];
+ let Args = [IdentifierArgument<"Module">,
+ VariadicParamIdxArgument<"Args">];
let Subjects = SubjectList<[HasFunctionProto]>;
let Documentation = [Undocumented];
}
@@ -1654,13 +1735,13 @@ def Packed : InheritableAttr {
let Documentation = [Undocumented];
}
-def IntelOclBicc : InheritableAttr {
- let Spellings = [Clang<"intel_ocl_bicc">];
+def IntelOclBicc : DeclOrTypeAttr {
+ let Spellings = [Clang<"intel_ocl_bicc", 0>];
// let Subjects = [Function, ObjCMethod];
let Documentation = [Undocumented];
}
-def Pcs : InheritableAttr {
+def Pcs : DeclOrTypeAttr {
let Spellings = [GCC<"pcs">];
let Args = [EnumArgument<"PCS", "PCSType",
["aapcs", "aapcs-vfp"],
@@ -1690,7 +1771,9 @@ def ReqdWorkGroupSize : InheritableAttr {
}
def RequireConstantInit : InheritableAttr {
- let Spellings = [Clang<"require_constant_initialization">];
+ // This attribute does not have a C [[]] spelling because it requires the
+ // CPlusPlus language option.
+ let Spellings = [Clang<"require_constant_initialization", 0>];
let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
let Documentation = [RequireConstantInitDocs];
let LangOpts = [CPlusPlus];
@@ -1721,6 +1804,13 @@ def Section : InheritableAttr {
let Documentation = [SectionDocs];
}
+def CodeSeg : InheritableAttr {
+ let Spellings = [Declspec<"code_seg">];
+ let Args = [StringArgument<"Name">];
+ let Subjects = SubjectList<[Function, CXXRecord], ErrorDiag>;
+ let Documentation = [CodeSegDocs];
+}
+
def PragmaClangBSSSection : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
@@ -1761,13 +1851,13 @@ def Sentinel : InheritableAttr {
let Documentation = [Undocumented];
}
-def StdCall : InheritableAttr {
+def StdCall : DeclOrTypeAttr {
let Spellings = [GCC<"stdcall">, Keyword<"__stdcall">, Keyword<"_stdcall">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [StdCallDocs];
}
-def SwiftCall : InheritableAttr {
+def SwiftCall : DeclOrTypeAttr {
let Spellings = [Clang<"swiftcall">];
// let Subjects = SubjectList<[Function]>;
let Documentation = [SwiftCallDocs];
@@ -1794,38 +1884,38 @@ def Suppress : StmtAttr {
let Documentation = [SuppressDocs];
}
-def SysVABI : InheritableAttr {
+def SysVABI : DeclOrTypeAttr {
let Spellings = [GCC<"sysv_abi">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [Undocumented];
}
-def ThisCall : InheritableAttr {
+def ThisCall : DeclOrTypeAttr {
let Spellings = [GCC<"thiscall">, Keyword<"__thiscall">,
Keyword<"_thiscall">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [ThisCallDocs];
}
-def VectorCall : InheritableAttr {
+def VectorCall : DeclOrTypeAttr {
let Spellings = [Clang<"vectorcall">, Keyword<"__vectorcall">,
Keyword<"_vectorcall">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [VectorCallDocs];
}
-def Pascal : InheritableAttr {
+def Pascal : DeclOrTypeAttr {
let Spellings = [Clang<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [Undocumented];
}
-def PreserveMost : InheritableAttr {
+def PreserveMost : DeclOrTypeAttr {
let Spellings = [Clang<"preserve_most">];
let Documentation = [PreserveMostDocs];
}
-def PreserveAll : InheritableAttr {
+def PreserveAll : DeclOrTypeAttr {
let Spellings = [Clang<"preserve_all">];
let Documentation = [PreserveAllDocs];
}
@@ -1840,12 +1930,27 @@ def Target : InheritableAttr {
std::vector<std::string> Features;
StringRef Architecture;
bool DuplicateArchitecture = false;
+ bool operator ==(const ParsedTargetAttr &Other) const {
+ return DuplicateArchitecture == Other.DuplicateArchitecture &&
+ Architecture == Other.Architecture && Features == Other.Features;
+ }
};
ParsedTargetAttr parse() const {
return parse(getFeaturesStr());
}
+
+ template<class Compare>
+ ParsedTargetAttr parse(Compare cmp) const {
+ ParsedTargetAttr Attrs = parse();
+ llvm::sort(std::begin(Attrs.Features), std::end(Attrs.Features), cmp);
+ return Attrs;
+ }
+
+ bool isDefaultVersion() const { return getFeaturesStr() == "default"; }
+
static ParsedTargetAttr parse(StringRef Features) {
ParsedTargetAttr Ret;
+ if (Features == "default") return Ret;
SmallVector<StringRef, 1> AttrFeatures;
Features.split(AttrFeatures, ",");
@@ -1861,7 +1966,7 @@ def Target : InheritableAttr {
// overall feature validity for the function with the rest of the
// attributes on the function.
if (Feature.startswith("fpmath=") || Feature.startswith("tune="))
- continue;
+ continue;
// While we're here iterating check for a different target cpu.
if (Feature.startswith("arch=")) {
@@ -1879,6 +1984,13 @@ def Target : InheritableAttr {
}];
}
+def MinVectorWidth : InheritableAttr {
+ let Spellings = [Clang<"min_vector_width">];
+ let Args = [UnsignedArgument<"VectorWidth">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [MinVectorWidthDocs];
+}
+
def TransparentUnion : InheritableAttr {
let Spellings = [GCC<"transparent_union">];
// let Subjects = SubjectList<[Record, TypedefName]>;
@@ -1913,7 +2025,7 @@ def DiagnoseIf : InheritableAttr {
["DT_Error", "DT_Warning"]>,
BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
NamedArgument<"Parent", 0, /*fake*/ 1>];
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let LateParsed = 1;
let AdditionalMembers = [{
bool isError() const { return diagnosticType == DT_Error; }
@@ -1958,6 +2070,7 @@ def Unused : InheritableAttr {
def Used : InheritableAttr {
let Spellings = [GCC<"used">];
+ let Subjects = SubjectList<[NonLocalVar, Function, ObjCMethod]>;
let Documentation = [Undocumented];
}
@@ -2006,7 +2119,10 @@ def TypeVisibility : InheritableAttr {
}
def VecReturn : InheritableAttr {
- let Spellings = [Clang<"vecreturn">];
+ // This attribute does not have a C [[]] spelling because it only appertains
+ // to C++ struct/class/union.
+ // FIXME: should this attribute have a CPlusPlus language option?
+ let Spellings = [Clang<"vecreturn", 0>];
let Subjects = SubjectList<[CXXRecord], ErrorDiag>;
let Documentation = [Undocumented];
}
@@ -2066,6 +2182,12 @@ def AnyX86NoCallerSavedRegisters : InheritableAttr,
let Documentation = [AnyX86NoCallerSavedRegistersDocs];
}
+def AnyX86NoCfCheck : InheritableAttr, TargetSpecificAttr<TargetAnyX86>{
+ let Spellings = [GCC<"nocf_check">];
+ let Subjects = SubjectList<[FunctionLike]>;
+ let Documentation = [AnyX86NoCfCheckDocs];
+}
+
def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetAnyX86> {
let Spellings = [GCC<"force_align_arg_pointer">];
// Technically, this appertains to a FunctionDecl, but the target-specific
@@ -2112,13 +2234,13 @@ def NoSanitizeSpecific : InheritableAttr {
// an updated captability-based name and the older name will only be supported
// under the GNU-style spelling.
def GuardedVar : InheritableAttr {
- let Spellings = [Clang<"guarded_var">];
+ let Spellings = [Clang<"guarded_var", 0>];
let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented];
}
def PtGuardedVar : InheritableAttr {
- let Spellings = [Clang<"pt_guarded_var">];
+ let Spellings = [Clang<"pt_guarded_var", 0>];
let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented];
}
@@ -2131,17 +2253,17 @@ def Lockable : InheritableAttr {
}
def ScopedLockable : InheritableAttr {
- let Spellings = [Clang<"scoped_lockable">];
+ let Spellings = [Clang<"scoped_lockable", 0>];
let Subjects = SubjectList<[Record]>;
let Documentation = [Undocumented];
}
def Capability : InheritableAttr {
- let Spellings = [Clang<"capability">, Clang<"shared_capability">];
+ let Spellings = [Clang<"capability", 0>, Clang<"shared_capability", 0>];
let Subjects = SubjectList<[Record, TypedefName], ErrorDiag>;
let Args = [StringArgument<"Name">];
let Accessors = [Accessor<"isShared",
- [Clang<"shared_capability">]>];
+ [Clang<"shared_capability", 0>]>];
let Documentation = [Undocumented];
let AdditionalMembers = [{
bool isMutex() const { return getName().equals_lower("mutex"); }
@@ -2150,83 +2272,83 @@ def Capability : InheritableAttr {
}
def AssertCapability : InheritableAttr {
- let Spellings = [Clang<"assert_capability">,
- Clang<"assert_shared_capability">];
+ let Spellings = [Clang<"assert_capability", 0>,
+ Clang<"assert_shared_capability", 0>];
let Subjects = SubjectList<[Function]>;
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Args = [VariadicExprArgument<"Args">];
let Accessors = [Accessor<"isShared",
- [Clang<"assert_shared_capability">]>];
+ [Clang<"assert_shared_capability", 0>]>];
let Documentation = [AssertCapabilityDocs];
}
def AcquireCapability : InheritableAttr {
- let Spellings = [Clang<"acquire_capability">,
- Clang<"acquire_shared_capability">,
+ let Spellings = [Clang<"acquire_capability", 0>,
+ Clang<"acquire_shared_capability", 0>,
GNU<"exclusive_lock_function">,
GNU<"shared_lock_function">];
let Subjects = SubjectList<[Function]>;
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Args = [VariadicExprArgument<"Args">];
let Accessors = [Accessor<"isShared",
- [Clang<"acquire_shared_capability">,
+ [Clang<"acquire_shared_capability", 0>,
GNU<"shared_lock_function">]>];
let Documentation = [AcquireCapabilityDocs];
}
def TryAcquireCapability : InheritableAttr {
- let Spellings = [Clang<"try_acquire_capability">,
- Clang<"try_acquire_shared_capability">];
+ let Spellings = [Clang<"try_acquire_capability", 0>,
+ Clang<"try_acquire_shared_capability", 0>];
let Subjects = SubjectList<[Function],
ErrorDiag>;
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
let Accessors = [Accessor<"isShared",
- [Clang<"try_acquire_shared_capability">]>];
+ [Clang<"try_acquire_shared_capability", 0>]>];
let Documentation = [TryAcquireCapabilityDocs];
}
def ReleaseCapability : InheritableAttr {
- let Spellings = [Clang<"release_capability">,
- Clang<"release_shared_capability">,
- Clang<"release_generic_capability">,
- Clang<"unlock_function">];
+ let Spellings = [Clang<"release_capability", 0>,
+ Clang<"release_shared_capability", 0>,
+ Clang<"release_generic_capability", 0>,
+ Clang<"unlock_function", 0>];
let Subjects = SubjectList<[Function]>;
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Args = [VariadicExprArgument<"Args">];
let Accessors = [Accessor<"isShared",
- [Clang<"release_shared_capability">]>,
+ [Clang<"release_shared_capability", 0>]>,
Accessor<"isGeneric",
- [Clang<"release_generic_capability">,
- Clang<"unlock_function">]>];
+ [Clang<"release_generic_capability", 0>,
+ Clang<"unlock_function", 0>]>];
let Documentation = [ReleaseCapabilityDocs];
}
def RequiresCapability : InheritableAttr {
- let Spellings = [Clang<"requires_capability">,
- Clang<"exclusive_locks_required">,
- Clang<"requires_shared_capability">,
- Clang<"shared_locks_required">];
+ let Spellings = [Clang<"requires_capability", 0>,
+ Clang<"exclusive_locks_required", 0>,
+ Clang<"requires_shared_capability", 0>,
+ Clang<"shared_locks_required", 0>];
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Subjects = SubjectList<[Function]>;
- let Accessors = [Accessor<"isShared", [Clang<"requires_shared_capability">,
- Clang<"shared_locks_required">]>];
+ let Accessors = [Accessor<"isShared", [Clang<"requires_shared_capability", 0>,
+ Clang<"shared_locks_required", 0>]>];
let Documentation = [Undocumented];
}
@@ -2242,7 +2364,7 @@ def GuardedBy : InheritableAttr {
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented];
}
@@ -2253,7 +2375,7 @@ def PtGuardedBy : InheritableAttr {
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented];
}
@@ -2264,7 +2386,7 @@ def AcquiredAfter : InheritableAttr {
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented];
}
@@ -2275,7 +2397,7 @@ def AcquiredBefore : InheritableAttr {
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented];
}
@@ -2286,7 +2408,7 @@ def AssertExclusiveLock : InheritableAttr {
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -2297,7 +2419,7 @@ def AssertSharedLock : InheritableAttr {
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -2310,7 +2432,7 @@ def ExclusiveTrylockFunction : InheritableAttr {
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -2323,7 +2445,7 @@ def SharedTrylockFunction : InheritableAttr {
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -2344,7 +2466,7 @@ def LocksExcluded : InheritableAttr {
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
+ let InheritEvenIfAlreadyPresent = 1;
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
@@ -2352,7 +2474,10 @@ def LocksExcluded : InheritableAttr {
// C/C++ consumed attributes.
def Consumable : InheritableAttr {
- let Spellings = [Clang<"consumable">];
+ // This attribute does not have a C [[]] spelling because it only appertains
+ // to C++ struct/class/union.
+ // FIXME: should this attribute have a CPlusPlus language option?
+ let Spellings = [Clang<"consumable", 0>];
let Subjects = SubjectList<[CXXRecord]>;
let Args = [EnumArgument<"DefaultState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
@@ -2361,19 +2486,28 @@ def Consumable : InheritableAttr {
}
def ConsumableAutoCast : InheritableAttr {
- let Spellings = [Clang<"consumable_auto_cast_state">];
+ // This attribute does not have a C [[]] spelling because it only appertains
+ // to C++ struct/class/union.
+ // FIXME: should this attribute have a CPlusPlus language option?
+ let Spellings = [Clang<"consumable_auto_cast_state", 0>];
let Subjects = SubjectList<[CXXRecord]>;
let Documentation = [Undocumented];
}
def ConsumableSetOnRead : InheritableAttr {
- let Spellings = [Clang<"consumable_set_state_on_read">];
+ // This attribute does not have a C [[]] spelling because it only appertains
+ // to C++ struct/class/union.
+ // FIXME: should this attribute have a CPlusPlus language option?
+ let Spellings = [Clang<"consumable_set_state_on_read", 0>];
let Subjects = SubjectList<[CXXRecord]>;
let Documentation = [Undocumented];
}
def CallableWhen : InheritableAttr {
- let Spellings = [Clang<"callable_when">];
+ // This attribute does not have a C [[]] spelling because it only appertains
+ // to C++ function (but doesn't require it to be a member function).
+ // FIXME: should this attribute have a CPlusPlus language option?
+ let Spellings = [Clang<"callable_when", 0>];
let Subjects = SubjectList<[CXXMethod]>;
let Args = [VariadicEnumArgument<"CallableStates", "ConsumedState",
["unknown", "consumed", "unconsumed"],
@@ -2382,7 +2516,10 @@ def CallableWhen : InheritableAttr {
}
def ParamTypestate : InheritableAttr {
- let Spellings = [Clang<"param_typestate">];
+ // This attribute does not have a C [[]] spelling because it only appertains
+ // to a parameter whose type is a consumable C++ class.
+ // FIXME: should this attribute have a CPlusPlus language option?
+ let Spellings = [Clang<"param_typestate", 0>];
let Subjects = SubjectList<[ParmVar]>;
let Args = [EnumArgument<"ParamState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
@@ -2391,7 +2528,10 @@ def ParamTypestate : InheritableAttr {
}
def ReturnTypestate : InheritableAttr {
- let Spellings = [Clang<"return_typestate">];
+ // This attribute does not have a C [[]] spelling because it only appertains
+ // to a parameter or function return type that is a consumable C++ class.
+ // FIXME: should this attribute have a CPlusPlus language option?
+ let Spellings = [Clang<"return_typestate", 0>];
let Subjects = SubjectList<[Function, ParmVar]>;
let Args = [EnumArgument<"State", "ConsumedState",
["unknown", "consumed", "unconsumed"],
@@ -2400,7 +2540,10 @@ def ReturnTypestate : InheritableAttr {
}
def SetTypestate : InheritableAttr {
- let Spellings = [Clang<"set_typestate">];
+ // This attribute does not have a C [[]] spelling because it only appertains
+ // to C++ function (but doesn't require it to be a member function).
+ // FIXME: should this attribute have a CPlusPlus language option?
+ let Spellings = [Clang<"set_typestate", 0>];
let Subjects = SubjectList<[CXXMethod]>;
let Args = [EnumArgument<"NewState", "ConsumedState",
["unknown", "consumed", "unconsumed"],
@@ -2409,7 +2552,10 @@ def SetTypestate : InheritableAttr {
}
def TestTypestate : InheritableAttr {
- let Spellings = [Clang<"test_typestate">];
+ // This attribute does not have a C [[]] spelling because it only appertains
+ // to C++ function (but doesn't require it to be a member function).
+ // FIXME: should this attribute have a CPlusPlus language option?
+ let Spellings = [Clang<"test_typestate", 0>];
let Subjects = SubjectList<[CXXMethod]>;
let Args = [EnumArgument<"TestState", "ConsumedState",
["consumed", "unconsumed"],
@@ -2420,18 +2566,18 @@ def TestTypestate : InheritableAttr {
// Type safety attributes for `void *' pointers and type tags.
def ArgumentWithTypeTag : InheritableAttr {
- let Spellings = [GNU<"argument_with_type_tag">,
- GNU<"pointer_with_type_tag">];
+ let Spellings = [Clang<"argument_with_type_tag">,
+ Clang<"pointer_with_type_tag">];
+ let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
let Args = [IdentifierArgument<"ArgumentKind">,
- UnsignedArgument<"ArgumentIdx">,
- UnsignedArgument<"TypeTagIdx">,
- BoolArgument<"IsPointer">];
- let HasCustomParsing = 1;
+ ParamIdxArgument<"ArgumentIdx">,
+ ParamIdxArgument<"TypeTagIdx">,
+ BoolArgument<"IsPointer", /*opt*/0, /*fake*/1>];
let Documentation = [ArgumentWithTypeTagDocs, PointerWithTypeTagDocs];
}
def TypeTagForDatatype : InheritableAttr {
- let Spellings = [GNU<"type_tag_for_datatype">];
+ let Spellings = [Clang<"type_tag_for_datatype">];
let Args = [IdentifierArgument<"ArgumentKind">,
TypeArgument<"MatchingCType">,
BoolArgument<"LayoutCompatible">,
@@ -2469,6 +2615,16 @@ def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
let Spellings = [Declspec<"dllimport">, GCC<"dllimport">];
let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
let Documentation = [DLLImportDocs];
+
+
+ let AdditionalMembers = [{
+private:
+ bool PropagatedToBaseTemplate = false;
+
+public:
+ void setPropagatedToBaseTemplate() { PropagatedToBaseTemplate = true; }
+ bool wasPropagatedToBaseTemplate() { return PropagatedToBaseTemplate; }
+ }];
}
def SelectAny : InheritableAttr {
@@ -2510,7 +2666,7 @@ def UPtr : TypeAttr {
def MSInheritance : InheritableAttr {
let LangOpts = [MicrosoftExt];
- let Args = [DefaultBoolArgument<"BestCase", 1>];
+ let Args = [DefaultBoolArgument<"BestCase", /*default*/1, /*fake*/1>];
let Spellings = [Keyword<"__single_inheritance">,
Keyword<"__multiple_inheritance">,
Keyword<"__virtual_inheritance">,
@@ -2565,7 +2721,7 @@ def InitSeg : Attr {
let Documentation = [InitSegDocs];
let AdditionalMembers = [{
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
- OS << '(' << getSection() << ')';
+ OS << " (" << getSection() << ')';
}
}];
}
@@ -2575,7 +2731,7 @@ def LoopHint : Attr {
/// vectorize: vectorizes loop operations if State == Enable.
/// vectorize_width: vectorize loop operations with width 'Value'.
/// interleave: interleave multiple loop iterations if State == Enable.
- /// interleave_count: interleaves 'Value' loop interations.
+ /// interleave_count: interleaves 'Value' loop iterations.
/// unroll: fully unroll loop if State == Enable.
/// unroll_count: unrolls loop 'Value' times.
/// distribute: attempt to distribute loop if State == Enable
@@ -2620,12 +2776,12 @@ def LoopHint : Attr {
if (SpellingIndex == Pragma_nounroll)
return;
else if (SpellingIndex == Pragma_unroll) {
- OS << getValueString(Policy);
+ OS << ' ' << getValueString(Policy);
return;
}
assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
- OS << getOptionName(option) << getValueString(Policy);
+ OS << ' ' << getOptionName(option) << getValueString(Policy);
}
// Return a string containing the loop hint argument including the
@@ -2693,6 +2849,14 @@ def OMPCaptureKind : Attr {
let Documentation = [Undocumented];
}
+def OMPReferencedVar : Attr {
+ // This attribute has no spellings as it is only ever created implicitly.
+ let Spellings = [];
+ let SemaHandler = 0;
+ let Args = [ExprArgument<"Ref">];
+ let Documentation = [Undocumented];
+}
+
def OMPDeclareSimdDecl : Attr {
let Spellings = [Pragma<"omp", "declare simd">];
let Subjects = SubjectList<[Function]>;
@@ -2712,37 +2876,37 @@ def OMPDeclareSimdDecl : Attr {
void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy)
const {
if (getBranchState() != BS_Undefined)
- OS << ConvertBranchStateTyToStr(getBranchState()) << " ";
+ OS << ' ' << ConvertBranchStateTyToStr(getBranchState());
if (auto *E = getSimdlen()) {
- OS << "simdlen(";
+ OS << " simdlen(";
E->printPretty(OS, nullptr, Policy);
- OS << ") ";
+ OS << ")";
}
if (uniforms_size() > 0) {
- OS << "uniform";
+ OS << " uniform";
StringRef Sep = "(";
for (auto *E : uniforms()) {
OS << Sep;
E->printPretty(OS, nullptr, Policy);
Sep = ", ";
}
- OS << ") ";
+ OS << ")";
}
alignments_iterator NI = alignments_begin();
for (auto *E : aligneds()) {
- OS << "aligned(";
+ OS << " aligned(";
E->printPretty(OS, nullptr, Policy);
if (*NI) {
OS << ": ";
(*NI)->printPretty(OS, nullptr, Policy);
}
- OS << ") ";
+ OS << ")";
++NI;
}
steps_iterator I = steps_begin();
modifiers_iterator MI = modifiers_begin();
for (auto *E : linears()) {
- OS << "linear(";
+ OS << " linear(";
if (*MI != OMPC_LINEAR_unknown)
OS << getOpenMPSimpleClauseTypeName(OMPC_linear, *MI) << "(";
E->printPretty(OS, nullptr, Policy);
@@ -2752,7 +2916,7 @@ def OMPDeclareSimdDecl : Attr {
OS << ": ";
(*I)->printPretty(OS, nullptr, Policy);
}
- OS << ") ";
+ OS << ")";
++I;
++MI;
}
@@ -2773,7 +2937,7 @@ def OMPDeclareTargetDecl : Attr {
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
// Use fake syntax because it is for testing and debugging purpose only.
if (getMapType() != MT_To)
- OS << ConvertMapTypeTyToStr(getMapType()) << " ";
+ OS << ' ' << ConvertMapTypeTyToStr(getMapType());
}
}];
}
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index ecff329c4ccba..5a5ab78b49d11 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -191,6 +191,65 @@ in generation of more efficient code.
}];
}
+def CPUSpecificCPUDispatchDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``cpu_specific`` and ``cpu_dispatch`` attributes are used to define and
+resolve multiversioned functions. This form of multiversioning provides a
+mechanism for declaring versions across translation units and manually
+specifying the resolved function list. A specified CPU defines a set of minimum
+features that are required for the function to be called. The result of this is
+that future processors execute the most restrictive version of the function the
+new processor can execute.
+
+Function versions are defined with ``cpu_specific``, which takes one or more CPU
+names as a parameter. For example:
+
+.. code-block:: c
+
+ // Declares and defines the ivybridge version of single_cpu.
+ __attribute__((cpu_specific(ivybridge)))
+ void single_cpu(void){}
+
+ // Declares and defines the atom version of single_cpu.
+ __attribute__((cpu_specific(atom)))
+ void single_cpu(void){}
+
+ // Declares and defines both the ivybridge and atom version of multi_cpu.
+ __attribute__((cpu_specific(ivybridge, atom)))
+ void multi_cpu(void){}
+
+A dispatching (or resolving) function can be declared anywhere in a project's
+source code with ``cpu_dispatch``. This attribute takes one or more CPU names
+as a parameter (like ``cpu_specific``). Functions marked with ``cpu_dispatch``
+are not expected to be defined, only declared. If such a marked function has a
+definition, any side effects of the function are ignored; trivial function
+bodies are permissible for ICC compatibility.
+
+.. code-block:: c
+
+ // Creates a resolver for single_cpu above.
+ __attribute__((cpu_dispatch(ivybridge, atom)))
+ void single_cpu(void){}
+
+ // Creates a resolver for multi_cpu, but adds a 3rd version defined in another
+ // translation unit.
+ __attribute__((cpu_dispatch(ivybridge, atom, sandybridge)))
+ void multi_cpu(void){}
+
+Note that it is possible to have a resolving function that dispatches based on
+more or fewer options than are present in the program. Specifying fewer will
+result in the omitted options not being considered during resolution. Specifying
+a version for resolution that isn't defined in the program will result in a
+linking failure.
+
+It is also possible to specify a CPU name of ``generic`` which will be resolved
+if the executing processor doesn't satisfy the features required in the CPU
+name. The behavior of a program executing on a processor that doesn't satisfy
+any option of a multiversioned function is undefined.
+ }];
+}
+
def C11NoReturnDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -273,7 +332,7 @@ def AllocSizeDocs : Documentation {
let Content = [{
The ``alloc_size`` attribute can be placed on functions that return pointers in
order to hint to the compiler how many bytes of memory will be available at the
-returned poiner. ``alloc_size`` takes one or two arguments.
+returned pointer. ``alloc_size`` takes one or two arguments.
- ``alloc_size(N)`` implies that argument number N equals the number of
available bytes at the returned pointer.
@@ -306,12 +365,24 @@ An example of how to use ``alloc_size``
}];
}
+def CodeSegDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``__declspec(code_seg)`` attribute enables the placement of code into separate
+named segments that can be paged or locked in memory individually. This attribute
+is used to control the placement of instantiated templates and compiler-generated
+code. See the documentation for `__declspec(code_seg)`_ on MSDN.
+
+.. _`__declspec(code_seg)`: http://msdn.microsoft.com/en-us/library/dn636922.aspx
+ }];
+}
+
def AllocAlignDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Use ``__attribute__((alloc_align(<alignment>))`` on a function
declaration to specify that the return value of the function (which must be a
-pointer type) is at least as aligned as the value of the indicated parameter. The
+pointer type) is at least as aligned as the value of the indicated parameter. The
parameter is given by its index in the list of formal parameters; the first
parameter has index 1 unless the function is a C++ non-static member function,
in which case the first parameter has index 2 to account for the implicit ``this``
@@ -330,7 +401,7 @@ parameter.
void *Foo::b(void *v, size_t align) __attribute__((alloc_align(3)));
Note that this attribute merely informs the compiler that a function always
-returns a sufficiently aligned pointer. It does not cause the compiler to
+returns a sufficiently aligned pointer. It does not cause the compiler to
emit code to enforce that alignment. The behavior is undefined if the returned
poitner is not sufficiently aligned.
}];
@@ -353,7 +424,7 @@ available in C.
int isdigit(int c);
int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
-
+
void foo(char c) {
isdigit(c);
isdigit(10);
@@ -406,7 +477,7 @@ overload out of a number of viable overloads using enable_if.
void f() __attribute__((enable_if(true, ""))); // #1
void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, ""))); // #2
-
+
void g(int i, int j) __attribute__((enable_if(i, ""))); // #1
void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true))); // #2
@@ -913,16 +984,16 @@ in the metadata name for that object. The `objc_runtime_name`
attribute allows annotated interfaces or protocols to use the
specified string argument in the object's metadata name instead of the
default name.
-
+
**Usage**: ``__attribute__((objc_runtime_name("MyLocalName")))``. This attribute
can only be placed before an @protocol or @interface declaration:
-
+
.. code-block:: objc
-
+
__attribute__((objc_runtime_name("MyLocalName")))
@interface Message
@end
-
+
}];
}
@@ -1228,7 +1299,7 @@ potentially-evaluated discarded-value expression that is not explicitly cast to
.. code-block: c++
struct [[nodiscard]] error_info { /*...*/ };
error_info enable_missile_safety_mode();
-
+
void launch_missiles();
void test_missiles() {
enable_missile_safety_mode(); // diagnoses
@@ -1430,6 +1501,29 @@ as ``-mlong-calls`` and ``-mno-long-calls``.
}];
}
+def RISCVInterruptDocs : Documentation {
+ let Category = DocCatFunction;
+ let Heading = "interrupt (RISCV)";
+ let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt))`` attribute on RISCV
+targets. This attribute may be attached to a function definition and instructs
+the backend to generate appropriate function entry/exit code so that it can be
+used directly as an interrupt service routine.
+
+Permissible values for this parameter are ``user``, ``supervisor``,
+and ``machine``. If there is no parameter, then it defaults to machine.
+
+Repeated interrupt attribute on the same declaration will cause a warning
+to be emitted. In case of repeated declarations, the last one prevails.
+
+Refer to:
+https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Function-Attributes.html
+https://riscv.org/specifications/privileged-isa/
+The RISC-V Instruction Set Manual Volume II: Privileged Architecture
+Version 1.10.
+ }];
+}
+
def AVRInterruptDocs : Documentation {
let Category = DocCatFunction;
let Heading = "interrupt (AVR)";
@@ -1474,6 +1568,49 @@ for the function.
Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2",
"avx", "xop" and largely correspond to the machine specific options handled by
the front end.
+
+Additionally, this attribute supports function multiversioning for ELF based
+x86/x86-64 targets, which can be used to create multiple implementations of the
+same function that will be resolved at runtime based on the priority of their
+``target`` attribute strings. A function is considered a multiversioned function
+if either two declarations of the function have different ``target`` attribute
+strings, or if it has a ``target`` attribute string of ``default``. For
+example:
+
+ .. code-block:: c++
+
+ __attribute__((target("arch=atom")))
+ void foo() {} // will be called on 'atom' processors.
+ __attribute__((target("default")))
+ void foo() {} // will be called on any other processors.
+
+All multiversioned functions must contain a ``default`` (fallback)
+implementation, otherwise usages of the function are considered invalid.
+Additionally, a function may not become multiversioned after its first use.
+}];
+}
+
+def MinVectorWidthDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the ``__attribute__((min_vector_width(width)))`` attribute. This
+attribute may be attached to a function and informs the backend that this
+function desires vectors of at least this width to be generated. Target-specific
+maximum vector widths still apply. This means even if you ask for something
+larger than the target supports, you will only get what the target supports.
+This attribute is meant to be a hint to control target heuristics that may
+generate narrower vectors than what the target hardware supports.
+
+This is currently used by the X86 target to allow some CPUs that support 512-bit
+vectors to be limited to using 256-bit vectors to avoid frequency penalties.
+This is currently enabled with the ``-prefer-vector-width=256`` command line
+option. The ``min_vector_width`` attribute can be used to prevent the backend
+from trying to split vector operations to match the ``prefer-vector-width``. All
+X86 vector intrinsics from x86intrin.h already set this attribute. Additionally,
+use of any of the X86-specific vector builtins will implicitly set this
+attribute on the calling function. The intent is that explicitly writing vector
+code using the X86 intrinsics will prevent ``prefer-vector-width`` from
+affecting the code.
}];
}
@@ -1785,13 +1922,14 @@ This attribute accepts a single parameter that must be one of the following:
def NoSanitizeDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
-Use the ``no_sanitize`` attribute on a function declaration to specify
-that a particular instrumentation or set of instrumentations should not be
-applied to that function. The attribute takes a list of string literals,
-which have the same meaning as values accepted by the ``-fno-sanitize=``
-flag. For example, ``__attribute__((no_sanitize("address", "thread")))``
-specifies that AddressSanitizer and ThreadSanitizer should not be applied
-to the function.
+Use the ``no_sanitize`` attribute on a function or a global variable
+declaration to specify that a particular instrumentation or set of
+instrumentations should not be applied. The attribute takes a list of
+string literals, which have the same meaning as values accepted by the
+``-fno-sanitize=`` flag. For example,
+``__attribute__((no_sanitize("address", "thread")))`` specifies that
+AddressSanitizer and ThreadSanitizer should not be applied to the
+function or variable.
See :ref:`Controlling Code Generation <controlling-code-generation>` for a
full list of supported sanitizer flags.
@@ -1806,9 +1944,9 @@ def NoSanitizeAddressDocs : Documentation {
let Content = [{
.. _langext-address_sanitizer:
-Use ``__attribute__((no_sanitize_address))`` on a function declaration to
-specify that address safety instrumentation (e.g. AddressSanitizer) should
-not be applied to that function.
+Use ``__attribute__((no_sanitize_address))`` on a function or a global
+variable declaration to specify that address safety instrumentation
+(e.g. AddressSanitizer) should not be applied.
}];
}
@@ -2224,6 +2362,48 @@ It is only supported when using the Microsoft C++ ABI.
}];
}
+def TrivialABIDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``trivial_abi`` attribute can be applied to a C++ class, struct, or union.
+It instructs the compiler to pass and return the type using the C ABI for the
+underlying type when the type would otherwise be considered non-trivial for the
+purpose of calls.
+A class annotated with `trivial_abi` can have non-trivial destructors or copy/move constructors without automatically becoming non-trivial for the purposes of calls. For example:
+
+ .. code-block:: c++
+
+ // A is trivial for the purposes of calls because `trivial_abi` makes the
+ // user-provided special functions trivial.
+ struct __attribute__((trivial_abi)) A {
+ ~A();
+ A(const A &);
+ A(A &&);
+ int x;
+ };
+
+ // B's destructor and copy/move constructor are considered trivial for the
+ // purpose of calls because A is trivial.
+ struct B {
+ A a;
+ };
+
+If a type is trivial for the purposes of calls, has a non-trivial destructor,
+and is passed as an argument by value, the convention is that the callee will
+destroy the object before returning.
+
+Attribute ``trivial_abi`` has no effect in the following cases:
+
+- The class directly declares a virtual base or virtual methods.
+- The class has a base class that is non-trivial for the purposes of calls.
+- The class has a non-static data member whose type is non-trivial for the purposes of calls, which includes:
+
+ - classes that are non-trivial for the purposes of calls
+ - __weak-qualified types in Objective-C++
+ - arrays of any of the above
+ }];
+}
+
def MSInheritanceDocs : Documentation {
let Category = DocCatType;
let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance";
@@ -2565,7 +2745,7 @@ The ``_Nullable`` nullability qualifier indicates that a value of the ``_Nullabl
int fetch_or_zero(int * _Nullable ptr);
-a caller of ``fetch_or_zero`` can provide null.
+a caller of ``fetch_or_zero`` can provide null.
}];
}
@@ -2641,23 +2821,23 @@ used to process multiple arguments from a single invocation from a SIMD loop
concurrently.
The syntax of the `declare simd` construct is as follows:
- .. code-block:: c
+ .. code-block:: none
- #pragma omp declare simd [clause[[,] clause] ...] new-line
- [#pragma omp declare simd [clause[[,] clause] ...] new-line]
- [...]
- function definition or declaration
+ #pragma omp declare simd [clause[[,] clause] ...] new-line
+ [#pragma omp declare simd [clause[[,] clause] ...] new-line]
+ [...]
+ function definition or declaration
where clause is one of the following:
- .. code-block:: c
+ .. code-block:: none
- simdlen(length)
- linear(argument-list[:constant-linear-step])
- aligned(argument-list[:alignment])
- uniform(argument-list)
- inbranch
- notinbranch
+ simdlen(length)
+ linear(argument-list[:constant-linear-step])
+ aligned(argument-list[:alignment])
+ uniform(argument-list)
+ inbranch
+ notinbranch
}];
}
@@ -2673,12 +2853,34 @@ The syntax of the declare target directive is as follows:
.. code-block:: c
- #pragma omp declare target new-line
- declarations-definition-seq
- #pragma omp end declare target new-line
+ #pragma omp declare target new-line
+ declarations-definition-seq
+ #pragma omp end declare target new-line
}];
}
+def NoStackProtectorDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the ``__attribute__((no_stack_protector))`` attribute which disables
+the stack protector on the specified function. This attribute is useful for
+selectively disabling the stack protector on some functions when building with
+``-fstack-protector`` compiler option.
+
+For example, it disables the stack protector for the function ``foo`` but function
+``bar`` will still be built with the stack protector with the ``-fstack-protector``
+option.
+
+.. code-block:: c
+
+ int __attribute__((no_stack_protector))
+ foo (int x); // stack protection will be disabled for foo.
+
+ int bar(int y); // bar can be built with the stack protector.
+
+ }];
+}
+
def NotTailCalledDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -2737,7 +2939,7 @@ def NoThrowDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Clang supports the GNU style ``__attribute__((nothrow))`` and Microsoft style
-``__declspec(nothrow)`` attribute as an equivilent of `noexcept` on function
+``__declspec(nothrow)`` attribute as an equivalent of `noexcept` on function
declarations. This attribute informs the compiler that the annotated function
does not throw an exception. This prevents exception-unwinding. This attribute
is particularly useful on functions in the C Standard Library that are
@@ -2800,7 +3002,7 @@ Use this attribute to indicate that the specified function has no
caller-saved registers. That is, all registers are callee-saved except for
registers used for passing parameters to the function or returning parameters
from the function.
-The compiler saves and restores any modified registers that were not used for
+The compiler saves and restores any modified registers that were not used for
passing or returning arguments to the function.
The user can call functions specified with the 'no_caller_saved_registers'
@@ -2852,6 +3054,23 @@ jumps from i386 arch code).
}];
}
+def AnyX86NoCfCheckDocs : Documentation{
+ let Category = DocCatFunction;
+ let Content = [{
+Jump Oriented Programming attacks rely on tampering with addresses used by
+indirect call / jmp, e.g. redirect control-flow to non-programmer
+intended bytes in the binary.
+X86 Supports Indirect Branch Tracking (IBT) as part of Control-Flow
+Enforcement Technology (CET). IBT instruments ENDBR instructions used to
+specify valid targets of indirect call / jmp.
+The ``nocf_check`` attribute has two roles:
+1. Appertains to a function - do not add ENDBR instruction at the beginning of
+the function.
+2. Appertains to a function pointer - do not track the target function of this
+pointer (by adding nocf_check prefix to the indirect-call instruction).
+}];
+}
+
def SwiftCallDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
@@ -3031,7 +3250,7 @@ the ability to distinguish between different versions of the same entity but
with different ABI versions supported. For example, a newer version of a class
could have a different set of data members and thus have a different size. Using
the ``abi_tag`` attribute, it is possible to have different mangled names for
-a global variable of the class type. Therefor, the old code could keep using
+a global variable of the class type. Therefore, the old code could keep using
the old manged name and the new code will use the new mangled name with tags.
}];
}
@@ -3213,3 +3432,13 @@ For more information see
or `msvc documentation <https://docs.microsoft.com/pl-pl/cpp/cpp/selectany>`_.
}];
}
+
+def ArtificialDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``artificial`` attribute can be applied to an inline function. If such a
+function is inlined, the attribute indicates that debuggers should associate
+the resulting instructions with the call site, rather than with the
+corresponding line within the inlined callee.
+ }];
+}
diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h
index 8f7394f59d4d1..d82dbb032be97 100644
--- a/include/clang/Basic/AttrKinds.h
+++ b/include/clang/Basic/AttrKinds.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the clang::attr::Kind enum.
+/// Defines the clang::attr::Kind enum.
///
//===----------------------------------------------------------------------===//
@@ -19,7 +19,7 @@ namespace clang {
namespace attr {
-// \brief A list of all the recognized kinds of attributes.
+// A list of all the recognized kinds of attributes.
enum Kind {
#define ATTR(X) X,
#define ATTR_RANGE(CLASS, FIRST_NAME, LAST_NAME) \
diff --git a/include/clang/Basic/AttrSubjectMatchRules.h b/include/clang/Basic/AttrSubjectMatchRules.h
index 4c88adf57f17d..81aa634dfeb86 100644
--- a/include/clang/Basic/AttrSubjectMatchRules.h
+++ b/include/clang/Basic/AttrSubjectMatchRules.h
@@ -16,7 +16,7 @@
namespace clang {
namespace attr {
-/// \brief A list of all the recognized kinds of attributes.
+/// A list of all the recognized kinds of attributes.
enum SubjectMatchRule {
#define ATTR_MATCH_RULE(X, Spelling, IsAbstract) X,
#include "clang/Basic/AttrSubMatchRulesList.inc"
diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h
index c651abacd482b..3152453694c9d 100644
--- a/include/clang/Basic/Attributes.h
+++ b/include/clang/Basic/Attributes.h
@@ -32,7 +32,7 @@ enum class AttrSyntax {
Pragma
};
-/// \brief Return the version number associated with the attribute if we
+/// Return the version number associated with the attribute if we
/// recognize and implement the attribute specified by the given information.
int hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
const IdentifierInfo *Attr, const TargetInfo &Target,
diff --git a/include/clang/Basic/BitmaskEnum.h b/include/clang/Basic/BitmaskEnum.h
new file mode 100644
index 0000000000000..12ff3cf207be3
--- /dev/null
+++ b/include/clang/Basic/BitmaskEnum.h
@@ -0,0 +1,25 @@
+//===--- BitmaskEnum.h - wrapper of LLVM's bitmask enum facility-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Provides LLVM's BitmaskEnum facility to enumeration types declared in
+/// namespace clang.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_BITMASKENUM_H
+#define LLVM_CLANG_BASIC_BITMASKENUM_H
+
+#include "llvm/ADT/BitmaskEnum.h"
+
+namespace clang {
+ LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+}
+
+#endif
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 3d4deb5ed3064..edd823754a374 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -48,8 +48,8 @@
// . -> "...". This may only occur at the end of the function list.
//
// Types may be prefixed with the following modifiers:
-// L -> long (e.g. Li for 'long int')
-// LL -> long long
+// L -> long (e.g. Li for 'long int', Ld for 'long double')
+// LL -> long long (e.g. LLi for 'long long int', LLd for __float128)
// LLL -> __int128_t (e.g. LLLi)
// W -> int64_t
// N -> 'int' size if target is LP64, 'L' otherwise.
@@ -89,9 +89,10 @@
// S:N: -> similar to the s:N: attribute, but the function is like vscanf
// in that it accepts its arguments as a va_list rather than
// through an ellipsis
-// e -> const, but only when -fmath-errno=0
+// e -> const, but only when -fno-math-errno
// j -> returns_twice (like setjmp)
// u -> arguments are not evaluated for their side-effects
+// V:N: -> requires vectors of at least N bits to be legal
// FIXME: gcc has nonnull
#if defined(BUILTIN) && !defined(LIBBUILTIN)
@@ -110,9 +111,11 @@ BUILTIN(__builtin_abs , "ii" , "ncF")
BUILTIN(__builtin_copysign, "ddd", "ncF")
BUILTIN(__builtin_copysignf, "fff", "ncF")
BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
+BUILTIN(__builtin_copysignf128, "LLdLLdLLd", "ncF")
BUILTIN(__builtin_fabs , "dd" , "ncF")
BUILTIN(__builtin_fabsf, "ff" , "ncF")
BUILTIN(__builtin_fabsl, "LdLd", "ncF")
+BUILTIN(__builtin_fabsf128, "LLdLLd", "ncF")
BUILTIN(__builtin_fmod , "ddd" , "Fne")
BUILTIN(__builtin_fmodf, "fff" , "Fne")
BUILTIN(__builtin_fmodl, "LdLdLd", "Fne")
@@ -122,9 +125,11 @@ BUILTIN(__builtin_frexpl, "LdLdi*", "Fn")
BUILTIN(__builtin_huge_val, "d", "nc")
BUILTIN(__builtin_huge_valf, "f", "nc")
BUILTIN(__builtin_huge_vall, "Ld", "nc")
+BUILTIN(__builtin_huge_valf128, "LLd", "nc")
BUILTIN(__builtin_inf , "d" , "nc")
BUILTIN(__builtin_inff , "f" , "nc")
BUILTIN(__builtin_infl , "Ld" , "nc")
+BUILTIN(__builtin_inff128 , "LLd" , "nc")
BUILTIN(__builtin_labs , "LiLi" , "Fnc")
BUILTIN(__builtin_llabs, "LLiLLi", "Fnc")
BUILTIN(__builtin_ldexp , "ddi" , "Fne")
@@ -133,12 +138,14 @@ BUILTIN(__builtin_ldexpl, "LdLdi", "Fne")
BUILTIN(__builtin_modf , "ddd*" , "Fn")
BUILTIN(__builtin_modff, "fff*" , "Fn")
BUILTIN(__builtin_modfl, "LdLdLd*", "Fn")
-BUILTIN(__builtin_nan, "dcC*" , "ncF")
-BUILTIN(__builtin_nanf, "fcC*" , "ncF")
-BUILTIN(__builtin_nanl, "LdcC*", "ncF")
-BUILTIN(__builtin_nans, "dcC*" , "ncF")
-BUILTIN(__builtin_nansf, "fcC*" , "ncF")
-BUILTIN(__builtin_nansl, "LdcC*", "ncF")
+BUILTIN(__builtin_nan, "dcC*" , "FnU")
+BUILTIN(__builtin_nanf, "fcC*" , "FnU")
+BUILTIN(__builtin_nanl, "LdcC*", "FnU")
+BUILTIN(__builtin_nanf128, "LLdcC*", "FnU")
+BUILTIN(__builtin_nans, "dcC*" , "FnU")
+BUILTIN(__builtin_nansf, "fcC*" , "FnU")
+BUILTIN(__builtin_nansl, "LdcC*", "FnU")
+BUILTIN(__builtin_nansf128, "LLdcC*", "FnU")
BUILTIN(__builtin_powi , "ddi" , "Fnc")
BUILTIN(__builtin_powif, "ffi" , "Fnc")
BUILTIN(__builtin_powil, "LdLdi", "Fnc")
@@ -715,6 +722,10 @@ ATOMIC_BUILTIN(__opencl_atomic_fetch_xor, "v.", "t")
ATOMIC_BUILTIN(__opencl_atomic_fetch_min, "v.", "t")
ATOMIC_BUILTIN(__opencl_atomic_fetch_max, "v.", "t")
+// GCC does not support these, they are a Clang extension.
+ATOMIC_BUILTIN(__atomic_fetch_min, "v.", "t")
+ATOMIC_BUILTIN(__atomic_fetch_max, "v.", "t")
+
#undef ATOMIC_BUILTIN
// Non-overloaded atomic builtins.
@@ -734,6 +745,14 @@ BUILTIN(__builtin_rindex, "c*cC*i", "Fn")
LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__annotation, "wC*.","n", ALL_MS_LANGUAGES)
LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittest, "UcNiC*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittestandcomplement, "UcNi*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittestandreset, "UcNi*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittestandset, "UcNi*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittest64, "UcWiC*Wi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittestandcomplement64, "UcWi*Wi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittestandreset64, "UcWi*Wi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_bittestandset64, "UcWi*Wi", "n", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_ulong, "UNiUNi", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_uint64, "ULLiULLi", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
@@ -773,7 +792,16 @@ LANGBUILTIN(_InterlockedOr, "NiNiD*Ni", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor8, "ccD*c", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor16, "ssD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor, "NiNiD*Ni", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_interlockedbittestandset, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandreset, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandreset64, "UcWiD*Wi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandreset_acq, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandreset_nf, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandreset_rel, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandset, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandset64, "UcWiD*Wi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandset_acq, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandset_nf, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_interlockedbittestandset_rel, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
@@ -796,6 +824,10 @@ LANGBUILTIN(__fastfail, "vUi", "nr", ALL_MS_LANGUAGES)
LIBBUILTIN(_setjmpex, "iJ", "fj", "setjmpex.h", ALL_MS_LANGUAGES)
// C99 library functions
+// C99 stdarg.h
+LIBBUILTIN(va_start, "vA.", "fn", "stdarg.h", ALL_LANGUAGES)
+LIBBUILTIN(va_end, "vA", "fn", "stdarg.h", ALL_LANGUAGES)
+LIBBUILTIN(va_copy, "vAA", "fn", "stdarg.h", ALL_LANGUAGES)
// C99 stdlib.h
LIBBUILTIN(abort, "v", "fr", "stdlib.h", ALL_LANGUAGES)
LIBBUILTIN(calloc, "v*zz", "f", "stdlib.h", ALL_LANGUAGES)
@@ -803,6 +835,13 @@ LIBBUILTIN(exit, "vi", "fr", "stdlib.h", ALL_LANGUAGES)
LIBBUILTIN(_Exit, "vi", "fr", "stdlib.h", ALL_LANGUAGES)
LIBBUILTIN(malloc, "v*z", "f", "stdlib.h", ALL_LANGUAGES)
LIBBUILTIN(realloc, "v*v*z", "f", "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(strtod, "dcC*c**", "f", "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(strtof, "fcC*c**", "f", "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(strtold, "LdcC*c**", "f", "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(strtol, "LicC*c**i", "f", "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(strtoll, "LLicC*c**i", "f", "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(strtoul, "ULicC*c**i", "f", "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(strtoull, "ULLicC*c**i", "f", "stdlib.h", ALL_LANGUAGES)
// C99 string.h
LIBBUILTIN(memcpy, "v*v*vC*z", "f", "string.h", ALL_LANGUAGES)
LIBBUILTIN(memcmp, "ivC*vC*z", "f", "string.h", ALL_LANGUAGES)
@@ -826,6 +865,7 @@ LIBBUILTIN(memset, "v*v*iz", "f", "string.h", ALL_LANGUAGES)
LIBBUILTIN(strerror, "c*i", "f", "string.h", ALL_LANGUAGES)
LIBBUILTIN(strlen, "zcC*", "f", "string.h", ALL_LANGUAGES)
// C99 stdio.h
+// FIXME: This list is incomplete.
LIBBUILTIN(printf, "icC*.", "fp:0:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(fprintf, "iP*cC*.", "fp:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(snprintf, "ic*zcC*.", "fp:2:", "stdio.h", ALL_LANGUAGES)
@@ -840,6 +880,10 @@ LIBBUILTIN(sscanf, "icC*RcC*R.", "fs:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(vscanf, "icC*Ra", "fS:0:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(vfscanf, "iP*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(vsscanf, "icC*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(fopen, "P*cC*cC*", "f", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(fread, "zv*zzP*", "f", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(fwrite, "zvC*zzP*", "f", "stdio.h", ALL_LANGUAGES)
+
// C99 ctype.h
LIBBUILTIN(isalnum, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
LIBBUILTIN(isalpha, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
@@ -1361,12 +1405,15 @@ BUILTIN(__builtin_smulll_overflow, "bSLLiCSLLiCSLLi*", "n")
// Clang builtins (not available in GCC).
BUILTIN(__builtin_addressof, "v*v&", "nct")
-BUILTIN(__builtin_operator_new, "v*z", "c")
-BUILTIN(__builtin_operator_delete, "vv*", "n")
+BUILTIN(__builtin_operator_new, "v*z", "tc")
+BUILTIN(__builtin_operator_delete, "vv*", "tn")
BUILTIN(__builtin_char_memchr, "c*cC*iz", "n")
+BUILTIN(__builtin_dump_struct, "ivC*v*", "tn")
// Safestack builtins
BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn")
+BUILTIN(__builtin___get_unsafe_stack_bottom, "v*", "Fn")
+BUILTIN(__builtin___get_unsafe_stack_top, "v*", "Fn")
BUILTIN(__builtin___get_unsafe_stack_ptr, "v*", "Fn")
// Nontemporal loads/stores builtins
@@ -1381,6 +1428,7 @@ BUILTIN(__builtin_coro_promise, "v*v*IiIb", "n")
BUILTIN(__builtin_coro_size, "z", "n")
BUILTIN(__builtin_coro_frame, "v*", "n")
+BUILTIN(__builtin_coro_noop, "v*", "n")
BUILTIN(__builtin_coro_free, "v*v*", "n")
BUILTIN(__builtin_coro_id, "v*Iiv*v*v*", "n")
@@ -1443,6 +1491,7 @@ LANGBUILTIN(omp_is_initial_device, "i", "nc", OMP_LANG)
// Builtins for XRay
BUILTIN(__xray_customevent, "vcC*z", "")
+BUILTIN(__xray_typedevent, "vzcC*z", "")
// Win64-compatible va_list functions
BUILTIN(__builtin_ms_va_start, "vc*&.", "nt")
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
index 963c72ea82e0e..fa2bcc4c7ab0b 100644
--- a/include/clang/Basic/Builtins.h
+++ b/include/clang/Basic/Builtins.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines enum values for all the target-independent builtin
+/// Defines enum values for all the target-independent builtin
/// functions.
///
//===----------------------------------------------------------------------===//
@@ -59,7 +59,7 @@ struct Info {
const char *Features;
};
-/// \brief Holds information about both target-independent and
+/// Holds information about both target-independent and
/// target-specific builtins, allowing easy queries by clients.
///
/// Builtins from an optional auxiliary target are stored in
@@ -72,122 +72,129 @@ class Context {
public:
Context() {}
- /// \brief Perform target-specific initialization
+ /// Perform target-specific initialization
/// \param AuxTarget Target info to incorporate builtins from. May be nullptr.
void InitializeTarget(const TargetInfo &Target, const TargetInfo *AuxTarget);
- /// \brief Mark the identifiers for all the builtins with their
+ /// Mark the identifiers for all the builtins with their
/// appropriate builtin ID # and mark any non-portable builtin identifiers as
/// such.
void initializeBuiltins(IdentifierTable &Table, const LangOptions& LangOpts);
- /// \brief Return the identifier name for the specified builtin,
+ /// Return the identifier name for the specified builtin,
/// e.g. "__builtin_abs".
const char *getName(unsigned ID) const {
return getRecord(ID).Name;
}
- /// \brief Get the type descriptor string for the specified builtin.
+ /// Get the type descriptor string for the specified builtin.
const char *getTypeString(unsigned ID) const {
return getRecord(ID).Type;
}
- /// \brief Return true if this function is a target-specific builtin.
+ /// Return true if this function is a target-specific builtin.
bool isTSBuiltin(unsigned ID) const {
return ID >= Builtin::FirstTSBuiltin;
}
- /// \brief Return true if this function has no side effects.
+ /// Return true if this function has no side effects.
bool isPure(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'U') != nullptr;
}
- /// \brief Return true if this function has no side effects and doesn't
+ /// Return true if this function has no side effects and doesn't
/// read memory.
bool isConst(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'c') != nullptr;
}
- /// \brief Return true if we know this builtin never throws an exception.
+ /// Return true if we know this builtin never throws an exception.
bool isNoThrow(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'n') != nullptr;
}
- /// \brief Return true if we know this builtin never returns.
+ /// Return true if we know this builtin never returns.
bool isNoReturn(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'r') != nullptr;
}
- /// \brief Return true if we know this builtin can return twice.
+ /// Return true if we know this builtin can return twice.
bool isReturnsTwice(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'j') != nullptr;
}
- /// \brief Returns true if this builtin does not perform the side-effects
+ /// Returns true if this builtin does not perform the side-effects
/// of its arguments.
bool isUnevaluated(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'u') != nullptr;
}
- /// \brief Return true if this is a builtin for a libc/libm function,
+ /// Return true if this is a builtin for a libc/libm function,
/// with a "__builtin_" prefix (e.g. __builtin_abs).
bool isLibFunction(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'F') != nullptr;
}
- /// \brief Determines whether this builtin is a predefined libc/libm
+ /// Determines whether this builtin is a predefined libc/libm
/// function, such as "malloc", where we know the signature a
/// priori.
bool isPredefinedLibFunction(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'f') != nullptr;
}
- /// \brief Returns true if this builtin requires appropriate header in other
+ /// Returns true if this builtin requires appropriate header in other
/// compilers. In Clang it will work even without including it, but we can emit
/// a warning about missing header.
bool isHeaderDependentFunction(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'h') != nullptr;
}
- /// \brief Determines whether this builtin is a predefined compiler-rt/libgcc
+ /// Determines whether this builtin is a predefined compiler-rt/libgcc
/// function, such as "__clear_cache", where we know the signature a
/// priori.
bool isPredefinedRuntimeFunction(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'i') != nullptr;
}
- /// \brief Determines whether this builtin has custom typechecking.
+ /// Determines whether this builtin has custom typechecking.
bool hasCustomTypechecking(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 't') != nullptr;
}
- /// \brief Determines whether this builtin has a result or any arguments which
+ /// Determines whether this builtin has a result or any arguments which
/// are pointer types.
bool hasPtrArgsOrResult(unsigned ID) const {
return strchr(getRecord(ID).Type, '*') != nullptr;
}
- /// \brief Completely forget that the given ID was ever considered a builtin,
+ /// Return true if this builtin has a result or any arguments which are
+ /// reference types.
+ bool hasReferenceArgsOrResult(unsigned ID) const {
+ return strchr(getRecord(ID).Type, '&') != nullptr ||
+ strchr(getRecord(ID).Type, 'A') != nullptr;
+ }
+
+ /// Completely forget that the given ID was ever considered a builtin,
/// e.g., because the user provided a conflicting signature.
void forgetBuiltin(unsigned ID, IdentifierTable &Table);
- /// \brief If this is a library function that comes from a specific
+ /// If this is a library function that comes from a specific
/// header, retrieve that header name.
const char *getHeaderName(unsigned ID) const {
return getRecord(ID).HeaderName;
}
- /// \brief Determine whether this builtin is like printf in its
+ /// Determine whether this builtin is like printf in its
/// formatting rules and, if so, set the index to the format string
/// argument and whether this function as a va_list argument.
bool isPrintfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg);
- /// \brief Determine whether this builtin is like scanf in its
+ /// Determine whether this builtin is like scanf in its
/// formatting rules and, if so, set the index to the format string
/// argument and whether this function as a va_list argument.
bool isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg);
- /// \brief Return true if this function has no side effects and doesn't
+ /// Return true if this function has no side effects and doesn't
/// read memory, except for possibly errno.
///
/// Such functions can be const when the MathErrno lang option is disabled.
@@ -199,12 +206,14 @@ public:
return getRecord(ID).Features;
}
- /// \brief Return true if builtin ID belongs to AuxTarget.
+ unsigned getRequiredVectorWidth(unsigned ID) const;
+
+ /// Return true if builtin ID belongs to AuxTarget.
bool isAuxBuiltinID(unsigned ID) const {
return ID >= (Builtin::FirstTSBuiltin + TSRecords.size());
}
- /// Return real buitin ID (i.e. ID it would have furing compilation
+ /// Return real builtin ID (i.e. ID it would have during compilation
/// for AuxTarget).
unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
@@ -212,26 +221,30 @@ public:
/// prefix.
static bool isBuiltinFunc(const char *Name);
+ /// Returns true if this is a builtin that can be redeclared. Returns true
+ /// for non-builtins.
+ bool canBeRedeclared(unsigned ID) const;
+
private:
const Info &getRecord(unsigned ID) const;
- /// \brief Is this builtin supported according to the given language options?
+ /// Is this builtin supported according to the given language options?
bool builtinIsSupported(const Builtin::Info &BuiltinInfo,
const LangOptions &LangOpts);
- /// \brief Helper function for isPrintfLike and isScanfLike.
+ /// Helper function for isPrintfLike and isScanfLike.
bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
const char *Fmt) const;
};
}
-/// \brief Kinds of BuiltinTemplateDecl.
+/// Kinds of BuiltinTemplateDecl.
enum BuiltinTemplateKind : int {
- /// \brief This names the __make_integer_seq BuiltinTemplateDecl.
+ /// This names the __make_integer_seq BuiltinTemplateDecl.
BTK__make_integer_seq,
- /// \brief This names the __type_pack_element BuiltinTemplateDecl.
+ /// This names the __type_pack_element BuiltinTemplateDecl.
BTK__type_pack_element
};
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
index 55a4f70176d00..b5d971d0bc6e4 100644
--- a/include/clang/Basic/BuiltinsAArch64.def
+++ b/include/clang/Basic/BuiltinsAArch64.def
@@ -18,6 +18,10 @@
# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
#endif
+#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN)
+# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
// In libgcc
BUILTIN(__clear_cache, "vv*v*", "i")
@@ -65,9 +69,40 @@ BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc")
BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc")
BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
+// MSVC
LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__yield, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfe, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfi, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__sev, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES)
+
+// MSVC intrinsics for volatile but non-acquire/release loads and stores
+LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES)
+
+TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
#undef BUILTIN
#undef LANGBUILTIN
+#undef TARGET_HEADER_BUILTIN
diff --git a/include/clang/Basic/BuiltinsAMDGPU.def b/include/clang/Basic/BuiltinsAMDGPU.def
index ec6a0fb917657..46cd738ae43f6 100644
--- a/include/clang/Basic/BuiltinsAMDGPU.def
+++ b/include/clang/Basic/BuiltinsAMDGPU.def
@@ -21,9 +21,9 @@
// SI+ only builtins.
//===----------------------------------------------------------------------===//
-BUILTIN(__builtin_amdgcn_dispatch_ptr, "Uc*2", "nc")
-BUILTIN(__builtin_amdgcn_kernarg_segment_ptr, "Uc*2", "nc")
-BUILTIN(__builtin_amdgcn_implicitarg_ptr, "Uc*2", "nc")
+BUILTIN(__builtin_amdgcn_dispatch_ptr, "Uc*4", "nc")
+BUILTIN(__builtin_amdgcn_kernarg_segment_ptr, "Uc*4", "nc")
+BUILTIN(__builtin_amdgcn_implicitarg_ptr, "Uc*4", "nc")
BUILTIN(__builtin_amdgcn_workgroup_id_x, "Ui", "nc")
BUILTIN(__builtin_amdgcn_workgroup_id_y, "Ui", "nc")
@@ -93,6 +93,9 @@ BUILTIN(__builtin_amdgcn_ds_bpermute, "iii", "nc")
BUILTIN(__builtin_amdgcn_readfirstlane, "ii", "nc")
BUILTIN(__builtin_amdgcn_readlane, "iii", "nc")
BUILTIN(__builtin_amdgcn_fmed3f, "ffff", "nc")
+BUILTIN(__builtin_amdgcn_ds_faddf, "ff*fIiIiIb", "n")
+BUILTIN(__builtin_amdgcn_ds_fminf, "ff*fIiIiIb", "n")
+BUILTIN(__builtin_amdgcn_ds_fmaxf, "ff*fIiIiIb", "n")
//===----------------------------------------------------------------------===//
// VI+ only builtins.
@@ -118,6 +121,18 @@ TARGET_BUILTIN(__builtin_amdgcn_mov_dpp, "iiIiIiIiIb", "nc", "dpp")
TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts")
//===----------------------------------------------------------------------===//
+// Deep learning builtins.
+//===----------------------------------------------------------------------===//
+
+TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hf", "nc", "dl-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSi", "nc", "dl-insts")
+TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUi", "nc", "dl-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSi", "nc", "dl-insts")
+TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUi", "nc", "dl-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSi", "nc", "dl-insts")
+TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUi", "nc", "dl-insts")
+
+//===----------------------------------------------------------------------===//
// Special builtins.
//===----------------------------------------------------------------------===//
BUILTIN(__builtin_amdgcn_read_exec, "LUi", "nc")
diff --git a/include/clang/Basic/BuiltinsHexagon.def b/include/clang/Basic/BuiltinsHexagon.def
index fda50b53589bd..f976720d116d0 100644
--- a/include/clang/Basic/BuiltinsHexagon.def
+++ b/include/clang/Basic/BuiltinsHexagon.def
@@ -17,28 +17,51 @@
// The builtins below are not autogenerated from iset.py.
// Make sure you do not overwrite these.
-BUILTIN(__builtin_brev_ldd, "LLi*LLi*LLi*i", "")
-BUILTIN(__builtin_brev_ldw, "i*i*i*i", "")
-BUILTIN(__builtin_brev_ldh, "s*s*s*i", "")
-BUILTIN(__builtin_brev_lduh, "Us*Us*Us*i", "")
-BUILTIN(__builtin_brev_ldb, "c*c*c*i", "")
-BUILTIN(__builtin_brev_ldub, "Uc*Uc*Uc*i", "")
+BUILTIN(__builtin_brev_ldd, "v*LLi*CLLi*iC", "")
+BUILTIN(__builtin_brev_ldw, "v*i*Ci*iC", "")
+BUILTIN(__builtin_brev_ldh, "v*s*Cs*iC", "")
+BUILTIN(__builtin_brev_lduh, "v*Us*CUs*iC", "")
+BUILTIN(__builtin_brev_ldb, "v*Sc*CSc*iC", "")
+BUILTIN(__builtin_brev_ldub, "v*Uc*CUc*iC", "")
BUILTIN(__builtin_circ_ldd, "LLi*LLi*LLi*iIi", "")
BUILTIN(__builtin_circ_ldw, "i*i*i*iIi", "")
BUILTIN(__builtin_circ_ldh, "s*s*s*iIi", "")
BUILTIN(__builtin_circ_lduh, "Us*Us*Us*iIi", "")
BUILTIN(__builtin_circ_ldb, "c*c*c*iIi", "")
BUILTIN(__builtin_circ_ldub, "Uc*Uc*Uc*iIi", "")
-BUILTIN(__builtin_brev_std, "LLi*LLi*LLii", "")
-BUILTIN(__builtin_brev_stw, "i*i*ii", "")
-BUILTIN(__builtin_brev_sth, "s*s*ii", "")
-BUILTIN(__builtin_brev_sthhi, "s*s*ii", "")
-BUILTIN(__builtin_brev_stb, "c*c*ii", "")
+BUILTIN(__builtin_brev_std, "LLi*CLLi*LLiiC", "")
+BUILTIN(__builtin_brev_stw, "i*Ci*iiC", "")
+BUILTIN(__builtin_brev_sth, "s*Cs*iiC", "")
+BUILTIN(__builtin_brev_sthhi, "s*Cs*iiC", "")
+BUILTIN(__builtin_brev_stb, "c*Cc*iiC", "")
BUILTIN(__builtin_circ_std, "LLi*LLi*LLiiIi", "")
BUILTIN(__builtin_circ_stw, "i*i*iiIi", "")
BUILTIN(__builtin_circ_sth, "s*s*iiIi", "")
BUILTIN(__builtin_circ_sthhi, "s*s*iiIi", "")
BUILTIN(__builtin_circ_stb, "c*c*iiIi", "")
+BUILTIN(__builtin_HEXAGON_L2_loadrub_pci, "iv*IiivC*", "")
+BUILTIN(__builtin_HEXAGON_L2_loadrb_pci, "iv*IiivC*", "")
+BUILTIN(__builtin_HEXAGON_L2_loadruh_pci, "iv*IiivC*", "")
+BUILTIN(__builtin_HEXAGON_L2_loadrh_pci, "iv*IiivC*", "")
+BUILTIN(__builtin_HEXAGON_L2_loadri_pci, "iv*IiivC*", "")
+BUILTIN(__builtin_HEXAGON_L2_loadrd_pci, "LLiv*IiivC*", "")
+BUILTIN(__builtin_HEXAGON_L2_loadrub_pcr, "iv*ivC*", "")
+BUILTIN(__builtin_HEXAGON_L2_loadrb_pcr, "iv*ivC*", "")
+BUILTIN(__builtin_HEXAGON_L2_loadruh_pcr, "iv*ivC*", "")
+BUILTIN(__builtin_HEXAGON_L2_loadrh_pcr, "iv*ivC*", "")
+BUILTIN(__builtin_HEXAGON_L2_loadri_pcr, "iv*ivC*", "")
+BUILTIN(__builtin_HEXAGON_L2_loadrd_pcr, "LLiv*ivC*", "")
+
+BUILTIN(__builtin_HEXAGON_S2_storerb_pci, "vv*IiiivC*", "")
+BUILTIN(__builtin_HEXAGON_S2_storerh_pci, "vv*IiiivC*", "")
+BUILTIN(__builtin_HEXAGON_S2_storerf_pci, "vv*IiiivC*", "")
+BUILTIN(__builtin_HEXAGON_S2_storeri_pci, "vv*IiiivC*", "")
+BUILTIN(__builtin_HEXAGON_S2_storerd_pci, "vv*IiiLLivC*", "")
+BUILTIN(__builtin_HEXAGON_S2_storerb_pcr, "vv*iivC*", "")
+BUILTIN(__builtin_HEXAGON_S2_storerh_pcr, "vv*iivC*", "")
+BUILTIN(__builtin_HEXAGON_S2_storerf_pcr, "vv*iivC*", "")
+BUILTIN(__builtin_HEXAGON_S2_storeri_pcr, "vv*iivC*", "")
+BUILTIN(__builtin_HEXAGON_S2_storerd_pcr, "vv*iLLivC*", "")
// The builtins above are not autogenerated from iset.py.
// Make sure you do not overwrite these.
diff --git a/include/clang/Basic/BuiltinsNEON.def b/include/clang/Basic/BuiltinsNEON.def
index 7800ae69c4c96..241b93a915a94 100644
--- a/include/clang/Basic/BuiltinsNEON.def
+++ b/include/clang/Basic/BuiltinsNEON.def
@@ -16,6 +16,7 @@
#define GET_NEON_BUILTINS
#include "clang/Basic/arm_neon.inc"
+#include "clang/Basic/arm_fp16.inc"
#undef GET_NEON_BUILTINS
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsNVPTX.def b/include/clang/Basic/BuiltinsNVPTX.def
index 7bab73a3b110c..08c60979779b7 100644
--- a/include/clang/Basic/BuiltinsNVPTX.def
+++ b/include/clang/Basic/BuiltinsNVPTX.def
@@ -18,6 +18,19 @@
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
+#pragma push_macro("SM_70")
+#define SM_70 "sm_70|sm_71"
+#pragma push_macro("SM_60")
+#define SM_60 "sm_60|sm_61|sm_62|" SM_70
+
+#pragma push_macro("PTX61")
+#define PTX61 "ptx61"
+#pragma push_macro("PTX60")
+#define PTX60 "ptx60|" PTX61
+
+#pragma push_macro("AND")
+#define AND(a, b) a "," b
+
// Special Registers
BUILTIN(__nvvm_read_ptx_sreg_tid_x, "i", "nc")
@@ -372,7 +385,7 @@ BUILTIN(__nvvm_bitcast_ll2d, "dLLi", "")
BUILTIN(__nvvm_bitcast_d2ll, "LLid", "")
// FNS
-TARGET_BUILTIN(__nvvm_fns, "UiUiUii", "n", "ptx60")
+TARGET_BUILTIN(__nvvm_fns, "UiUiUii", "n", PTX60)
// Sync
@@ -381,9 +394,9 @@ BUILTIN(__nvvm_bar0_popc, "ii", "")
BUILTIN(__nvvm_bar0_and, "ii", "")
BUILTIN(__nvvm_bar0_or, "ii", "")
BUILTIN(__nvvm_bar_sync, "vi", "n")
-TARGET_BUILTIN(__nvvm_bar_warp_sync, "vUi", "n", "ptx60")
-TARGET_BUILTIN(__nvvm_barrier_sync, "vUi", "n", "ptx60")
-TARGET_BUILTIN(__nvvm_barrier_sync_cnt, "vUiUi", "n", "ptx60")
+TARGET_BUILTIN(__nvvm_bar_warp_sync, "vUi", "n", PTX60)
+TARGET_BUILTIN(__nvvm_barrier_sync, "vUi", "n", PTX60)
+TARGET_BUILTIN(__nvvm_barrier_sync_cnt, "vUiUi", "n", PTX60)
// Shuffle
@@ -396,14 +409,14 @@ BUILTIN(__nvvm_shfl_bfly_f32, "ffii", "")
BUILTIN(__nvvm_shfl_idx_i32, "iiii", "")
BUILTIN(__nvvm_shfl_idx_f32, "ffii", "")
-TARGET_BUILTIN(__nvvm_shfl_sync_down_i32, "iUiiii", "", "ptx60")
-TARGET_BUILTIN(__nvvm_shfl_sync_down_f32, "fUifii", "", "ptx60")
-TARGET_BUILTIN(__nvvm_shfl_sync_up_i32, "iUiiii", "", "ptx60")
-TARGET_BUILTIN(__nvvm_shfl_sync_up_f32, "fUifii", "", "ptx60")
-TARGET_BUILTIN(__nvvm_shfl_sync_bfly_i32, "iUiiii", "", "ptx60")
-TARGET_BUILTIN(__nvvm_shfl_sync_bfly_f32, "fUifii", "", "ptx60")
-TARGET_BUILTIN(__nvvm_shfl_sync_idx_i32, "iUiiii", "", "ptx60")
-TARGET_BUILTIN(__nvvm_shfl_sync_idx_f32, "fUifii", "", "ptx60")
+TARGET_BUILTIN(__nvvm_shfl_sync_down_i32, "iUiiii", "", PTX60)
+TARGET_BUILTIN(__nvvm_shfl_sync_down_f32, "fUifii", "", PTX60)
+TARGET_BUILTIN(__nvvm_shfl_sync_up_i32, "iUiiii", "", PTX60)
+TARGET_BUILTIN(__nvvm_shfl_sync_up_f32, "fUifii", "", PTX60)
+TARGET_BUILTIN(__nvvm_shfl_sync_bfly_i32, "iUiiii", "", PTX60)
+TARGET_BUILTIN(__nvvm_shfl_sync_bfly_f32, "fUifii", "", PTX60)
+TARGET_BUILTIN(__nvvm_shfl_sync_idx_i32, "iUiiii", "", PTX60)
+TARGET_BUILTIN(__nvvm_shfl_sync_idx_f32, "fUifii", "", PTX60)
// Vote
BUILTIN(__nvvm_vote_all, "bb", "")
@@ -411,17 +424,17 @@ BUILTIN(__nvvm_vote_any, "bb", "")
BUILTIN(__nvvm_vote_uni, "bb", "")
BUILTIN(__nvvm_vote_ballot, "Uib", "")
-TARGET_BUILTIN(__nvvm_vote_all_sync, "bUib", "", "ptx60")
-TARGET_BUILTIN(__nvvm_vote_any_sync, "bUib", "", "ptx60")
-TARGET_BUILTIN(__nvvm_vote_uni_sync, "bUib", "", "ptx60")
-TARGET_BUILTIN(__nvvm_vote_ballot_sync, "UiUib", "", "ptx60")
+TARGET_BUILTIN(__nvvm_vote_all_sync, "bUib", "", PTX60)
+TARGET_BUILTIN(__nvvm_vote_any_sync, "bUib", "", PTX60)
+TARGET_BUILTIN(__nvvm_vote_uni_sync, "bUib", "", PTX60)
+TARGET_BUILTIN(__nvvm_vote_ballot_sync, "UiUib", "", PTX60)
// Match
-TARGET_BUILTIN(__nvvm_match_any_sync_i32, "UiUiUi", "", "ptx60")
-TARGET_BUILTIN(__nvvm_match_any_sync_i64, "WiUiWi", "", "ptx60")
+TARGET_BUILTIN(__nvvm_match_any_sync_i32, "UiUiUi", "", PTX60)
+TARGET_BUILTIN(__nvvm_match_any_sync_i64, "WiUiWi", "", PTX60)
// These return a pair {value, predicate}, which requires custom lowering.
-TARGET_BUILTIN(__nvvm_match_all_sync_i32p, "UiUiUii*", "", "ptx60")
-TARGET_BUILTIN(__nvvm_match_all_sync_i64p, "WiUiWii*", "", "ptx60")
+TARGET_BUILTIN(__nvvm_match_all_sync_i32p, "UiUiUii*", "", PTX60)
+TARGET_BUILTIN(__nvvm_match_all_sync_i64p, "WiUiWii*", "", PTX60)
// Membar
@@ -462,194 +475,120 @@ BUILTIN(__builtin_ptx_get_image_channel_orderi_, "ii", "")
// - they are used in address space analysis and optimization
// So it does not hurt to expose them as builtins.
//
-BUILTIN(__nvvm_atom_add_g_i, "iiD*1i", "n")
-BUILTIN(__nvvm_atom_add_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_add_gen_i, "iiD*i", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_add_gen_i, "iiD*i", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_add_gen_i, "iiD*i", "n", "satom")
-BUILTIN(__nvvm_atom_add_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_add_s_l, "LiLiD*3Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_add_gen_i, "iiD*i", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_add_gen_i, "iiD*i", "n", SM_60)
BUILTIN(__nvvm_atom_add_gen_l, "LiLiD*Li", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_add_gen_l, "LiLiD*Li", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_add_gen_l, "LiLiD*Li", "n", "satom")
-BUILTIN(__nvvm_atom_add_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_add_s_ll, "LLiLLiD*3LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_add_gen_l, "LiLiD*Li", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_add_gen_l, "LiLiD*Li", "n", SM_60)
BUILTIN(__nvvm_atom_add_gen_ll, "LLiLLiD*LLi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_add_gen_ll, "LLiLLiD*LLi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_add_gen_ll, "LLiLLiD*LLi", "n", "satom")
-BUILTIN(__nvvm_atom_add_g_f, "ffD*1f", "n")
-BUILTIN(__nvvm_atom_add_s_f, "ffD*3f", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_add_gen_ll, "LLiLLiD*LLi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_add_gen_ll, "LLiLLiD*LLi", "n", SM_60)
BUILTIN(__nvvm_atom_add_gen_f, "ffD*f", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_add_gen_f, "ffD*f", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_add_gen_f, "ffD*f", "n", "satom")
-BUILTIN(__nvvm_atom_add_g_d, "ddD*1d", "n")
-BUILTIN(__nvvm_atom_add_s_d, "ddD*3d", "n")
-TARGET_BUILTIN(__nvvm_atom_add_gen_d, "ddD*d", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_cta_add_gen_d, "ddD*d", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_add_gen_d, "ddD*d", "n", "satom")
-
-BUILTIN(__nvvm_atom_sub_g_i, "iiD*1i", "n")
-BUILTIN(__nvvm_atom_sub_s_i, "iiD*3i", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_add_gen_f, "ffD*f", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_add_gen_f, "ffD*f", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_add_gen_d, "ddD*d", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_cta_add_gen_d, "ddD*d", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_add_gen_d, "ddD*d", "n", SM_60)
+
BUILTIN(__nvvm_atom_sub_gen_i, "iiD*i", "n")
-BUILTIN(__nvvm_atom_sub_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_sub_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_sub_gen_l, "LiLiD*Li", "n")
-BUILTIN(__nvvm_atom_sub_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_sub_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_sub_gen_ll, "LLiLLiD*LLi", "n")
-BUILTIN(__nvvm_atom_xchg_g_i, "iiD*1i", "n")
-BUILTIN(__nvvm_atom_xchg_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_xchg_gen_i, "iiD*i", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_i, "iiD*i", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_i, "iiD*i", "n", "satom")
-BUILTIN(__nvvm_atom_xchg_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_xchg_s_l, "LiLiD*3Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_i, "iiD*i", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_i, "iiD*i", "n", SM_60)
BUILTIN(__nvvm_atom_xchg_gen_l, "LiLiD*Li", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_l, "LiLiD*Li", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_l, "LiLiD*Li", "n", "satom")
-BUILTIN(__nvvm_atom_xchg_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_xchg_s_ll, "LLiLLiD*3LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_l, "LiLiD*Li", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_l, "LiLiD*Li", "n", SM_60)
BUILTIN(__nvvm_atom_xchg_gen_ll, "LLiLLiD*LLi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_ll, "LLiLLiD*LLi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_ll, "LLiLLiD*LLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_ll, "LLiLLiD*LLi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_ll, "LLiLLiD*LLi", "n", SM_60)
-BUILTIN(__nvvm_atom_max_g_i, "iiD*1i", "n")
-BUILTIN(__nvvm_atom_max_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_max_gen_i, "iiD*i", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_max_gen_i, "iiD*i", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_max_gen_i, "iiD*i", "n", "satom")
-BUILTIN(__nvvm_atom_max_g_ui, "UiUiD*1Ui", "n")
-BUILTIN(__nvvm_atom_max_s_ui, "UiUiD*3Ui", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_max_gen_i, "iiD*i", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_max_gen_i, "iiD*i", "n", SM_60)
BUILTIN(__nvvm_atom_max_gen_ui, "UiUiD*Ui", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ui, "UiUiD*Ui", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ui, "UiUiD*Ui", "n", "satom")
-BUILTIN(__nvvm_atom_max_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_max_s_l, "LiLiD*3Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ui, "UiUiD*Ui", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ui, "UiUiD*Ui", "n", SM_60)
BUILTIN(__nvvm_atom_max_gen_l, "LiLiD*Li", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_max_gen_l, "LiLiD*Li", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_max_gen_l, "LiLiD*Li", "n", "satom")
-BUILTIN(__nvvm_atom_max_g_ul, "ULiULiD*1ULi", "n")
-BUILTIN(__nvvm_atom_max_s_ul, "ULiULiD*3ULi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_max_gen_l, "LiLiD*Li", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_max_gen_l, "LiLiD*Li", "n", SM_60)
BUILTIN(__nvvm_atom_max_gen_ul, "ULiULiD*ULi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ul, "ULiULiD*ULi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ul, "ULiULiD*ULi", "n", "satom")
-BUILTIN(__nvvm_atom_max_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_max_s_ll, "LLiLLiD*3LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ul, "ULiULiD*ULi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ul, "ULiULiD*ULi", "n", SM_60)
BUILTIN(__nvvm_atom_max_gen_ll, "LLiLLiD*LLi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ll, "LLiLLiD*LLi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ll, "LLiLLiD*LLi", "n", "satom")
-BUILTIN(__nvvm_atom_max_g_ull, "ULLiULLiD*1ULLi", "n")
-BUILTIN(__nvvm_atom_max_s_ull, "ULLiULLiD*3ULLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ll, "LLiLLiD*LLi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ll, "LLiLLiD*LLi", "n", SM_60)
BUILTIN(__nvvm_atom_max_gen_ull, "ULLiULLiD*ULLi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ull, "ULLiULLiD*ULLi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ull, "ULLiULLiD*ULLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ull, "ULLiULLiD*ULLi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ull, "ULLiULLiD*ULLi", "n", SM_60)
-BUILTIN(__nvvm_atom_min_g_i, "iiD*1i", "n")
-BUILTIN(__nvvm_atom_min_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_min_gen_i, "iiD*i", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_min_gen_i, "iiD*i", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_min_gen_i, "iiD*i", "n", "satom")
-BUILTIN(__nvvm_atom_min_g_ui, "UiUiD*1Ui", "n")
-BUILTIN(__nvvm_atom_min_s_ui, "UiUiD*3Ui", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_min_gen_i, "iiD*i", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_min_gen_i, "iiD*i", "n", SM_60)
BUILTIN(__nvvm_atom_min_gen_ui, "UiUiD*Ui", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ui, "UiUiD*Ui", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ui, "UiUiD*Ui", "n", "satom")
-BUILTIN(__nvvm_atom_min_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_min_s_l, "LiLiD*3Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ui, "UiUiD*Ui", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ui, "UiUiD*Ui", "n", SM_60)
BUILTIN(__nvvm_atom_min_gen_l, "LiLiD*Li", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_min_gen_l, "LiLiD*Li", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_min_gen_l, "LiLiD*Li", "n", "satom")
-BUILTIN(__nvvm_atom_min_g_ul, "ULiULiD*1ULi", "n")
-BUILTIN(__nvvm_atom_min_s_ul, "ULiULiD*3ULi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_min_gen_l, "LiLiD*Li", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_min_gen_l, "LiLiD*Li", "n", SM_60)
BUILTIN(__nvvm_atom_min_gen_ul, "ULiULiD*ULi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ul, "ULiULiD*ULi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ul, "ULiULiD*ULi", "n", "satom")
-BUILTIN(__nvvm_atom_min_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_min_s_ll, "LLiLLiD*3LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ul, "ULiULiD*ULi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ul, "ULiULiD*ULi", "n", SM_60)
BUILTIN(__nvvm_atom_min_gen_ll, "LLiLLiD*LLi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ll, "LLiLLiD*LLi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ll, "LLiLLiD*LLi", "n", "satom")
-BUILTIN(__nvvm_atom_min_g_ull, "ULLiULLiD*1ULLi", "n")
-BUILTIN(__nvvm_atom_min_s_ull, "ULLiULLiD*3ULLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ll, "LLiLLiD*LLi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ll, "LLiLLiD*LLi", "n", SM_60)
BUILTIN(__nvvm_atom_min_gen_ull, "ULLiULLiD*ULLi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ull, "ULLiULLiD*ULLi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ull, "ULLiULLiD*ULLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ull, "ULLiULLiD*ULLi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ull, "ULLiULLiD*ULLi", "n", SM_60)
-BUILTIN(__nvvm_atom_inc_g_ui, "UiUiD*1Ui", "n")
-BUILTIN(__nvvm_atom_inc_s_ui, "UiUiD*3Ui", "n")
BUILTIN(__nvvm_atom_inc_gen_ui, "UiUiD*Ui", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_inc_gen_ui, "UiUiD*Ui", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_inc_gen_ui, "UiUiD*Ui", "n", "satom")
-BUILTIN(__nvvm_atom_dec_g_ui, "UiUiD*1Ui", "n")
-BUILTIN(__nvvm_atom_dec_s_ui, "UiUiD*3Ui", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_inc_gen_ui, "UiUiD*Ui", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_inc_gen_ui, "UiUiD*Ui", "n", SM_60)
BUILTIN(__nvvm_atom_dec_gen_ui, "UiUiD*Ui", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_dec_gen_ui, "UiUiD*Ui", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_dec_gen_ui, "UiUiD*Ui", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_cta_dec_gen_ui, "UiUiD*Ui", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_dec_gen_ui, "UiUiD*Ui", "n", SM_60)
-BUILTIN(__nvvm_atom_and_g_i, "iiD*1i", "n")
-BUILTIN(__nvvm_atom_and_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_and_gen_i, "iiD*i", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_and_gen_i, "iiD*i", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_and_gen_i, "iiD*i", "n", "satom")
-BUILTIN(__nvvm_atom_and_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_and_s_l, "LiLiD*3Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_and_gen_i, "iiD*i", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_and_gen_i, "iiD*i", "n", SM_60)
BUILTIN(__nvvm_atom_and_gen_l, "LiLiD*Li", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_and_gen_l, "LiLiD*Li", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_and_gen_l, "LiLiD*Li", "n", "satom")
-BUILTIN(__nvvm_atom_and_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_and_s_ll, "LLiLLiD*3LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_and_gen_l, "LiLiD*Li", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_and_gen_l, "LiLiD*Li", "n", SM_60)
BUILTIN(__nvvm_atom_and_gen_ll, "LLiLLiD*LLi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_and_gen_ll, "LLiLLiD*LLi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_and_gen_ll, "LLiLLiD*LLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_cta_and_gen_ll, "LLiLLiD*LLi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_and_gen_ll, "LLiLLiD*LLi", "n", SM_60)
-BUILTIN(__nvvm_atom_or_g_i, "iiD*1i", "n")
-BUILTIN(__nvvm_atom_or_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_or_gen_i, "iiD*i", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_or_gen_i, "iiD*i", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_or_gen_i, "iiD*i", "n", "satom")
-BUILTIN(__nvvm_atom_or_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_or_s_l, "LiLiD*3Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_or_gen_i, "iiD*i", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_or_gen_i, "iiD*i", "n", SM_60)
BUILTIN(__nvvm_atom_or_gen_l, "LiLiD*Li", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_or_gen_l, "LiLiD*Li", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_or_gen_l, "LiLiD*Li", "n", "satom")
-BUILTIN(__nvvm_atom_or_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_or_s_ll, "LLiLLiD*3LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_or_gen_l, "LiLiD*Li", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_or_gen_l, "LiLiD*Li", "n", SM_60)
BUILTIN(__nvvm_atom_or_gen_ll, "LLiLLiD*LLi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_or_gen_ll, "LLiLLiD*LLi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_or_gen_ll, "LLiLLiD*LLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_cta_or_gen_ll, "LLiLLiD*LLi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_or_gen_ll, "LLiLLiD*LLi", "n", SM_60)
-BUILTIN(__nvvm_atom_xor_g_i, "iiD*1i", "n")
-BUILTIN(__nvvm_atom_xor_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_xor_gen_i, "iiD*i", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_i, "iiD*i", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_i, "iiD*i", "n", "satom")
-BUILTIN(__nvvm_atom_xor_g_l, "LiLiD*1Li", "n")
-BUILTIN(__nvvm_atom_xor_s_l, "LiLiD*3Li", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_i, "iiD*i", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_i, "iiD*i", "n", SM_60)
BUILTIN(__nvvm_atom_xor_gen_l, "LiLiD*Li", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_l, "LiLiD*Li", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_l, "LiLiD*Li", "n", "satom")
-BUILTIN(__nvvm_atom_xor_g_ll, "LLiLLiD*1LLi", "n")
-BUILTIN(__nvvm_atom_xor_s_ll, "LLiLLiD*3LLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_l, "LiLiD*Li", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_l, "LiLiD*Li", "n", SM_60)
BUILTIN(__nvvm_atom_xor_gen_ll, "LLiLLiD*LLi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_ll, "LLiLLiD*LLi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_ll, "LLiLLiD*LLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_ll, "LLiLLiD*LLi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_ll, "LLiLLiD*LLi", "n", SM_60)
-BUILTIN(__nvvm_atom_cas_g_i, "iiD*1ii", "n")
-BUILTIN(__nvvm_atom_cas_s_i, "iiD*3ii", "n")
BUILTIN(__nvvm_atom_cas_gen_i, "iiD*ii", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_i, "iiD*ii", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_i, "iiD*ii", "n", "satom")
-BUILTIN(__nvvm_atom_cas_g_l, "LiLiD*1LiLi", "n")
-BUILTIN(__nvvm_atom_cas_s_l, "LiLiD*3LiLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_i, "iiD*ii", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_i, "iiD*ii", "n", SM_60)
BUILTIN(__nvvm_atom_cas_gen_l, "LiLiD*LiLi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_l, "LiLiD*LiLi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_l, "LiLiD*LiLi", "n", "satom")
-BUILTIN(__nvvm_atom_cas_g_ll, "LLiLLiD*1LLiLLi", "n")
-BUILTIN(__nvvm_atom_cas_s_ll, "LLiLLiD*3LLiLLi", "n")
+TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_l, "LiLiD*LiLi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_l, "LiLiD*LiLi", "n", SM_60)
BUILTIN(__nvvm_atom_cas_gen_ll, "LLiLLiD*LLiLLi", "n")
-TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_ll, "LLiLLiD*LLiLLi", "n", "satom")
-TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_ll, "LLiLLiD*LLiLLi", "n", "satom")
+TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_ll, "LLiLLiD*LLiLLi", "n", SM_60)
+TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_ll, "LLiLLiD*LLiLLi", "n", SM_60)
// Compiler Error Warn
BUILTIN(__nvvm_compiler_error, "vcC*4", "n")
@@ -692,17 +631,46 @@ BUILTIN(__nvvm_ldg_f4, "E4fE4fC*", "")
BUILTIN(__nvvm_ldg_d2, "E2dE2dC*", "")
// Builtins to support WMMA instructions on sm_70
-TARGET_BUILTIN(__hmma_m16n16k16_ld_a, "vi*iC*UiIi", "", "ptx60")
-TARGET_BUILTIN(__hmma_m16n16k16_ld_b, "vi*iC*UiIi", "", "ptx60")
-TARGET_BUILTIN(__hmma_m16n16k16_ld_c_f16, "vi*iC*UiIi", "", "ptx60")
-TARGET_BUILTIN(__hmma_m16n16k16_ld_c_f32, "vf*fC*UiIi", "", "ptx60")
-TARGET_BUILTIN(__hmma_m16n16k16_st_c_f16, "vi*i*UiIi", "", "ptx60")
-TARGET_BUILTIN(__hmma_m16n16k16_st_c_f32, "vf*f*UiIi", "", "ptx60")
-
-TARGET_BUILTIN(__hmma_m16n16k16_mma_f16f16, "vi*iC*iC*iC*IiIi", "", "ptx60")
-TARGET_BUILTIN(__hmma_m16n16k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", "ptx60")
-TARGET_BUILTIN(__hmma_m16n16k16_mma_f32f32, "vf*iC*iC*fC*IiIi", "", "ptx60")
-TARGET_BUILTIN(__hmma_m16n16k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", "ptx60")
+TARGET_BUILTIN(__hmma_m16n16k16_ld_a, "vi*iC*UiIi", "", AND(SM_70,PTX60))
+TARGET_BUILTIN(__hmma_m16n16k16_ld_b, "vi*iC*UiIi", "", AND(SM_70,PTX60))
+TARGET_BUILTIN(__hmma_m16n16k16_ld_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX60))
+TARGET_BUILTIN(__hmma_m16n16k16_ld_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX60))
+TARGET_BUILTIN(__hmma_m16n16k16_st_c_f16, "vi*i*UiIi", "", AND(SM_70,PTX60))
+TARGET_BUILTIN(__hmma_m16n16k16_st_c_f32, "vf*f*UiIi", "", AND(SM_70,PTX60))
+
+TARGET_BUILTIN(__hmma_m32n8k16_ld_a, "vi*iC*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m32n8k16_ld_b, "vi*iC*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m32n8k16_ld_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m32n8k16_ld_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m32n8k16_st_c_f16, "vi*i*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m32n8k16_st_c_f32, "vf*f*UiIi", "", AND(SM_70,PTX61))
+
+TARGET_BUILTIN(__hmma_m8n32k16_ld_a, "vi*iC*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m8n32k16_ld_b, "vi*iC*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m8n32k16_ld_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m8n32k16_ld_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m8n32k16_st_c_f16, "vi*i*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m8n32k16_st_c_f32, "vf*f*UiIi", "", AND(SM_70,PTX61))
+
+TARGET_BUILTIN(__hmma_m16n16k16_mma_f16f16, "vi*iC*iC*iC*IiIi", "", AND(SM_70,PTX60))
+TARGET_BUILTIN(__hmma_m16n16k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", AND(SM_70,PTX60))
+TARGET_BUILTIN(__hmma_m16n16k16_mma_f32f32, "vf*iC*iC*fC*IiIi", "", AND(SM_70,PTX60))
+TARGET_BUILTIN(__hmma_m16n16k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", AND(SM_70,PTX60))
+
+TARGET_BUILTIN(__hmma_m32n8k16_mma_f16f16, "vi*iC*iC*iC*IiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m32n8k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m32n8k16_mma_f32f32, "vf*iC*iC*fC*IiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m32n8k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", AND(SM_70,PTX61))
+
+TARGET_BUILTIN(__hmma_m8n32k16_mma_f16f16, "vi*iC*iC*iC*IiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m8n32k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m8n32k16_mma_f32f32, "vf*iC*iC*fC*IiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m8n32k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", AND(SM_70,PTX61))
#undef BUILTIN
#undef TARGET_BUILTIN
+#pragma pop_macro("AND")
+#pragma pop_macro("SM_60")
+#pragma pop_macro("SM_70")
+#pragma pop_macro("PTX60")
+#pragma pop_macro("PTX61")
diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
index faa70a48edc3c..8cd8a2be20030 100644
--- a/include/clang/Basic/BuiltinsPPC.def
+++ b/include/clang/Basic/BuiltinsPPC.def
@@ -423,6 +423,15 @@ BUILTIN(__builtin_vsx_extractuword, "V2ULLiV16UcIi", "")
BUILTIN(__builtin_vsx_xxpermdi, "v.", "t")
BUILTIN(__builtin_vsx_xxsldwi, "v.", "t")
+// Float 128 built-ins
+BUILTIN(__builtin_sqrtf128_round_to_odd, "LLdLLd", "")
+BUILTIN(__builtin_addf128_round_to_odd, "LLdLLdLLd", "")
+BUILTIN(__builtin_subf128_round_to_odd, "LLdLLdLLd", "")
+BUILTIN(__builtin_mulf128_round_to_odd, "LLdLLdLLd", "")
+BUILTIN(__builtin_divf128_round_to_odd, "LLdLLdLLd", "")
+BUILTIN(__builtin_fmaf128_round_to_odd, "LLdLLdLLdLLd", "")
+BUILTIN(__builtin_truncf128_round_to_odd, "dLLd", "")
+
// HTM builtins
BUILTIN(__builtin_tbegin, "UiUIi", "")
BUILTIN(__builtin_tend, "UiUIi", "")
diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def
index 19318dcebb9ec..b3d877dcedf38 100644
--- a/include/clang/Basic/BuiltinsWebAssembly.def
+++ b/include/clang/Basic/BuiltinsWebAssembly.def
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief This file defines the WebAssembly-specific builtin function database.
+/// This file defines the WebAssembly-specific builtin function database.
/// Users of this file must define the BUILTIN macro to make use of this
/// information.
///
@@ -16,8 +16,17 @@
// The format of this database matches clang/Basic/Builtins.def.
-// Note that current_memory is not "c" (readnone) because it must be sequenced
-// with respect to grow_memory calls.
+// Query the current memory size, and increase the current memory size.
+// Note that memory.size is not "c" (readnone) because it must be sequenced
+// with respect to memory.grow calls.
+BUILTIN(__builtin_wasm_memory_size, "zIi", "n")
+BUILTIN(__builtin_wasm_memory_grow, "zIiz", "n")
+
+// These are the old names.
+BUILTIN(__builtin_wasm_mem_size, "zIi", "n")
+BUILTIN(__builtin_wasm_mem_grow, "zIiz", "n")
+
+// These are the old old names. They also lack the immediate field.
BUILTIN(__builtin_wasm_current_memory, "z", "n")
BUILTIN(__builtin_wasm_grow_memory, "zz", "n")
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 465551be77427..e98f7d612c3c6 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -27,8 +27,6 @@
# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
-// FIXME: Are these nothrow/const?
-
// Miscellaneous builtin for checking x86 cpu features.
// TODO: Make this somewhat generic so that other backends
// can use it?
@@ -38,9 +36,9 @@ BUILTIN(__builtin_cpu_is, "bcC*", "nc")
// Undefined Values
//
-TARGET_BUILTIN(__builtin_ia32_undef128, "V2d", "nc", "")
-TARGET_BUILTIN(__builtin_ia32_undef256, "V4d", "nc", "")
-TARGET_BUILTIN(__builtin_ia32_undef512, "V8d", "nc", "")
+TARGET_BUILTIN(__builtin_ia32_undef128, "V2d", "ncV:128:", "")
+TARGET_BUILTIN(__builtin_ia32_undef256, "V4d", "ncV:256:", "")
+TARGET_BUILTIN(__builtin_ia32_undef512, "V8d", "ncV:512:", "")
// FLAGS
//
@@ -49,33 +47,33 @@ TARGET_BUILTIN(__builtin_ia32_writeeflags_u32, "vUi", "n", "")
// 3DNow!
//
-TARGET_BUILTIN(__builtin_ia32_femms, "v", "", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pavgusb, "V8cV8cV8c", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pf2id, "V2iV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfacc, "V2fV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfadd, "V2fV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfcmpeq, "V2iV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfcmpge, "V2iV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfcmpgt, "V2iV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfmax, "V2fV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfmin, "V2fV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfmul, "V2fV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfrcp, "V2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfrcpit1, "V2fV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfrcpit2, "V2fV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfrsqrt, "V2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfrsqit1, "V2fV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfsub, "V2fV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pfsubr, "V2fV2fV2f", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pi2fd, "V2fV2i", "nc", "3dnow")
-TARGET_BUILTIN(__builtin_ia32_pmulhrw, "V4sV4sV4s", "nc", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_femms, "v", "n", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pavgusb, "V8cV8cV8c", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pf2id, "V2iV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfacc, "V2fV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfadd, "V2fV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfcmpeq, "V2iV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfcmpge, "V2iV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfcmpgt, "V2iV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfmax, "V2fV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfmin, "V2fV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfmul, "V2fV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfrcp, "V2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfrcpit1, "V2fV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfrcpit2, "V2fV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfrsqrt, "V2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfrsqit1, "V2fV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfsub, "V2fV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pfsubr, "V2fV2fV2f", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pi2fd, "V2fV2i", "ncV:64:", "3dnow")
+TARGET_BUILTIN(__builtin_ia32_pmulhrw, "V4sV4sV4s", "ncV:64:", "3dnow")
// 3DNow! Extensions (3dnowa).
-TARGET_BUILTIN(__builtin_ia32_pf2iw, "V2iV2f", "nc", "3dnowa")
-TARGET_BUILTIN(__builtin_ia32_pfnacc, "V2fV2fV2f", "nc", "3dnowa")
-TARGET_BUILTIN(__builtin_ia32_pfpnacc, "V2fV2fV2f", "nc", "3dnowa")
-TARGET_BUILTIN(__builtin_ia32_pi2fw, "V2fV2i", "nc", "3dnowa")
-TARGET_BUILTIN(__builtin_ia32_pswapdsf, "V2fV2f", "nc", "3dnowa")
-TARGET_BUILTIN(__builtin_ia32_pswapdsi, "V2iV2i", "nc", "3dnowa")
+TARGET_BUILTIN(__builtin_ia32_pf2iw, "V2iV2f", "ncV:64:", "3dnowa")
+TARGET_BUILTIN(__builtin_ia32_pfnacc, "V2fV2fV2f", "ncV:64:", "3dnowa")
+TARGET_BUILTIN(__builtin_ia32_pfpnacc, "V2fV2fV2f", "ncV:64:", "3dnowa")
+TARGET_BUILTIN(__builtin_ia32_pi2fw, "V2fV2i", "ncV:64:", "3dnowa")
+TARGET_BUILTIN(__builtin_ia32_pswapdsf, "V2fV2f", "ncV:64:", "3dnowa")
+TARGET_BUILTIN(__builtin_ia32_pswapdsi, "V2iV2i", "ncV:64:", "3dnowa")
// MMX
//
@@ -86,1808 +84,1758 @@ TARGET_BUILTIN(__builtin_ia32_pswapdsi, "V2iV2i", "nc", "3dnowa")
// argument and our prior approach of using a #define to the current built-in
// doesn't work in the presence of re-declaration of _mm_prefetch for windows.
TARGET_BUILTIN(_mm_prefetch, "vcC*i", "nc", "mmx")
-TARGET_BUILTIN(__builtin_ia32_emms, "v", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_paddd, "V2iV2iV2i", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psubb, "V8cV8cV8c", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psubw, "V4sV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psubd, "V2iV2iV2i", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pand, "V1LLiV1LLiV1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pandn, "V1LLiV1LLiV1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_por, "V1LLiV1LLiV1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pxor, "V1LLiV1LLiV1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psllw, "V4sV4sV1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pslld, "V2iV2iV1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psllq, "V1LLiV1LLiV1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psrld, "V2iV2iV1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psrlq, "V1LLiV1LLiV1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psraw, "V4sV4sV1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psrad, "V2iV2iV1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psllqi, "V1LLiV1LLii", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psrlqi, "V1LLiV1LLii", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_punpckhbw, "V8cV8cV8c", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_punpckhwd, "V4sV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_punpckhdq, "V2iV2iV2i", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_punpcklbw, "V8cV8cV8c", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_punpcklwd, "V4sV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_punpckldq, "V2iV2iV2i", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqb, "V8cV8cV8c", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqw, "V4sV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pcmpeqd, "V2iV2iV2i", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_movntq, "vV1LLi*V1LLi", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "", "mmx")
-TARGET_BUILTIN(__builtin_ia32_vec_ext_v2si, "iV2ii", "", "mmx")
+TARGET_BUILTIN(__builtin_ia32_emms, "v", "n", "mmx")
+TARGET_BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_paddd, "V2iV2iV2i", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psubb, "V8cV8cV8c", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psubw, "V4sV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psubd, "V2iV2iV2i", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pand, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pandn, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_por, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pxor, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psllw, "V4sV4sV1LLi", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pslld, "V2iV2iV1LLi", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psllq, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1LLi", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psrld, "V2iV2iV1LLi", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psrlq, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psraw, "V4sV4sV1LLi", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psrad, "V2iV2iV1LLi", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psllqi, "V1LLiV1LLii", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psrlqi, "V1LLiV1LLii", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_punpckhbw, "V8cV8cV8c", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_punpckhwd, "V4sV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_punpckhdq, "V2iV2iV2i", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_punpcklbw, "V8cV8cV8c", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_punpcklwd, "V4sV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_punpckldq, "V2iV2iV2i", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pcmpeqb, "V8cV8cV8c", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pcmpeqw, "V4sV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pcmpeqd, "V2iV2iV2i", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "nV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_movntq, "vV1LLi*V1LLi", "nV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "ncV:64:", "mmx")
+TARGET_BUILTIN(__builtin_ia32_vec_ext_v2si, "iV2ii", "ncV:64:", "mmx")
// MMX2 (MMX+SSE) intrinsics
-TARGET_BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_pshufw, "V4sV4sIc", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_vec_ext_v4hi, "iV4sIi", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4siIi", "", "sse")
+TARGET_BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_pshufw, "V4sV4sIc", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_vec_ext_v4hi, "iV4sIi", "ncV:64:", "mmx,sse")
+TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4siIi", "ncV:64:", "mmx,sse")
// MMX+SSE2
-TARGET_BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_paddq, "V1LLiV1LLiV1LLi", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psubq, "V1LLiV1LLiV1LLi", "", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "ncV:64:", "mmx,sse2")
+TARGET_BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "ncV:64:", "mmx,sse2")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "ncV:64:", "mmx,sse2")
+TARGET_BUILTIN(__builtin_ia32_paddq, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx,sse2")
+TARGET_BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "ncV:64:", "mmx,sse2")
+TARGET_BUILTIN(__builtin_ia32_psubq, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx,sse2")
// MMX+SSSE3
-TARGET_BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cIc", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cIc", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "ncV:64:", "mmx,ssse3")
+TARGET_BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "ncV:64:", "mmx,ssse3")
// SSE intrinsics.
-TARGET_BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_comilt, "iV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_comile, "iV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_comigt, "iV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_comige, "iV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_comineq, "iV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_ucomieq, "iV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_ucomilt, "iV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_ucomile, "iV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_ucomigt, "iV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_ucomige, "iV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_ucomineq, "iV4fV4f", "", "sse")
-
-TARGET_BUILTIN(__builtin_ia32_comisdeq, "iV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_comisdlt, "iV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_comisdle, "iV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_comisdgt, "iV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_comisdge, "iV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_comisdneq, "iV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_ucomisdeq, "iV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_ucomisdlt, "iV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_ucomisdle, "iV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_ucomisdgt, "iV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_ucomisdge, "iV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_ucomisdneq, "iV2dV2d", "", "sse2")
-
-TARGET_BUILTIN(__builtin_ia32_cmpeqps, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpltps, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpleps, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpunordps, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpneqps, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpnltps, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpnleps, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpordps, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpeqss, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpltss, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpless, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpunordss, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpneqss, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpnltss, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpnless, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cmpordss, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_minps, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_maxps, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_minss, "V4fV4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_maxss, "V4fV4fV4f", "", "sse")
-
-TARGET_BUILTIN(__builtin_ia32_cmpeqpd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpltpd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmplepd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpunordpd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpneqpd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpnltpd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpnlepd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpordpd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpeqsd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpltsd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmplesd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpunordsd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpneqsd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpnltsd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpnlesd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cmpordsd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_maxsd, "V2dV2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_paddsb128, "V16cV16cV16c", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_paddsw128, "V8sV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psubsb128, "V16cV16cV16c", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psubsw128, "V8sV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_paddusb128, "V16cV16cV16c", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pminsw128, "V8sV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_packsswb128, "V16cV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_packssdw128, "V8sV4iV4i", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_packuswb128, "V16cV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pmulhuw128, "V8sV8sV8s", "", "sse2")
-
-TARGET_BUILTIN(__builtin_ia32_addsubps, "V4fV4fV4f", "", "sse3")
-TARGET_BUILTIN(__builtin_ia32_addsubpd, "V2dV2dV2d", "", "sse3")
-TARGET_BUILTIN(__builtin_ia32_haddps, "V4fV4fV4f", "", "sse3")
-TARGET_BUILTIN(__builtin_ia32_haddpd, "V2dV2dV2d", "", "sse3")
-TARGET_BUILTIN(__builtin_ia32_hsubps, "V4fV4fV4f", "", "sse3")
-TARGET_BUILTIN(__builtin_ia32_hsubpd, "V2dV2dV2d", "", "sse3")
-TARGET_BUILTIN(__builtin_ia32_phaddw128, "V8sV8sV8s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_phaddd128, "V4iV4iV4i", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_phaddsw128, "V8sV8sV8s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_phsubw128, "V8sV8sV8s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_phsubd128, "V4iV4iV4i", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_phsubsw128, "V8sV8sV8s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_pmaddubsw128, "V8sV16cV16c", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_pmulhrsw128, "V8sV8sV8s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_pabsb128, "V16cV16c", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "", "ssse3")
-TARGET_BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "", "ssse3")
-
-TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "", "sse")
-TARGET_HEADER_BUILTIN(_mm_setcsr, "vUi", "h","xmmintrin.h", ALL_LANGUAGES, "sse")
-TARGET_BUILTIN(__builtin_ia32_stmxcsr, "Ui", "", "sse")
-TARGET_HEADER_BUILTIN(_mm_getcsr, "Ui", "h", "xmmintrin.h", ALL_LANGUAGES, "sse")
-TARGET_BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cvttss2si, "iV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_movmskps, "iV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_sfence, "v", "", "sse")
-TARGET_HEADER_BUILTIN(_mm_sfence, "v", "h", "xmmintrin.h", ALL_LANGUAGES, "sse")
-TARGET_BUILTIN(__builtin_ia32_rcpps, "V4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_rcpss, "V4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_rsqrtps, "V4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_rsqrtss, "V4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_sqrtps, "V4fV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_sqrtss, "V4fV4f", "", "sse")
-
-TARGET_BUILTIN(__builtin_ia32_maskmovdqu, "vV16cV16cc*", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_movmskpd, "iV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pmovmskb128, "iV16c", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_movnti, "vi*i", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_movnti64, "vLLi*LLi", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psadbw128, "V2LLiV16cV16c", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_sqrtpd, "V2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvtdq2ps, "V4fV4i", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvttsd2si, "iV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvtsd2ss, "V4fV4fV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_clflush, "vvC*", "", "sse2")
-TARGET_HEADER_BUILTIN(_mm_clflush, "vvC*", "h", "emmintrin.h", ALL_LANGUAGES, "sse2")
-TARGET_BUILTIN(__builtin_ia32_lfence, "v", "", "sse2")
-TARGET_HEADER_BUILTIN(_mm_lfence, "v", "h", "emmintrin.h", ALL_LANGUAGES, "sse2")
-TARGET_BUILTIN(__builtin_ia32_mfence, "v", "", "sse2")
-TARGET_HEADER_BUILTIN(_mm_mfence, "v", "h", "emmintrin.h", ALL_LANGUAGES, "sse2")
-TARGET_BUILTIN(__builtin_ia32_pause, "v", "", "")
-TARGET_HEADER_BUILTIN(_mm_pause, "v", "h", "emmintrin.h", ALL_LANGUAGES, "")
-TARGET_BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psrlw128, "V8sV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psrld128, "V4iV4iV4i", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psrlq128, "V2LLiV2LLiV2LLi", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psllw128, "V8sV8sV8s", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pslld128, "V4iV4iV4i", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psllq128, "V2LLiV2LLiV2LLi", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psllwi128, "V8sV8si", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pslldi128, "V4iV4ii", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psllqi128, "V2LLiV2LLii", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psrlwi128, "V8sV8si", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psrldi128, "V4iV4ii", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psrlqi128, "V2LLiV2LLii", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psrawi128, "V8sV8si", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psradi128, "V4iV4ii", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_pmaddwd128, "V4iV8sV8s", "", "sse2")
-
-TARGET_BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "", "sse3")
-TARGET_BUILTIN(__builtin_ia32_mwait, "vUiUi", "", "sse3")
-TARGET_BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "", "sse3")
-
-TARGET_BUILTIN(__builtin_ia32_palignr128, "V16cV16cV16cIi", "", "ssse3")
-
-TARGET_BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fIc", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pblendvb128, "V16cV16cV16cV16c", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_blendvpd, "V2dV2dV2dV2d", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_blendvps, "V4fV4fV4fV4f", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_packusdw128, "V8sV4iV4i", "", "sse4.1")
-
-TARGET_BUILTIN(__builtin_ia32_pmaxsb128, "V16cV16cV16c", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pmaxsd128, "V4iV4iV4i", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pmaxud128, "V4iV4iV4i", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pmaxuw128, "V8sV8sV8s", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pminsb128, "V16cV16cV16c", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pminsd128, "V4iV4iV4i", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pminud128, "V4iV4iV4i", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pminuw128, "V8sV8sV8s", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_pmuldq128, "V2LLiV4iV4i", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_roundps, "V4fV4fIi", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fIi", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2dIi", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_roundpd, "V2dV2dIi", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fIc", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_dppd, "V2dV2dV2dIc", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16cIc", "", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_phminposuw128, "V8sV8s", "", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_comilt, "iV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_comile, "iV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_comigt, "iV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_comige, "iV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_comineq, "iV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_ucomieq, "iV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_ucomilt, "iV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_ucomile, "iV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_ucomigt, "iV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_ucomige, "iV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_ucomineq, "iV4fV4f", "ncV:128:", "sse")
+
+TARGET_BUILTIN(__builtin_ia32_comisdeq, "iV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_comisdlt, "iV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_comisdle, "iV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_comisdgt, "iV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_comisdge, "iV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_comisdneq, "iV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_ucomisdeq, "iV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_ucomisdlt, "iV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_ucomisdle, "iV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_ucomisdgt, "iV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_ucomisdge, "iV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_ucomisdneq, "iV2dV2d", "ncV:128:", "sse2")
+
+TARGET_BUILTIN(__builtin_ia32_cmpeqps, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpltps, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpleps, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpunordps, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpneqps, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpnltps, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpnleps, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpordps, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpeqss, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpltss, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpless, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpunordss, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpneqss, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpnltss, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpnless, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cmpordss, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_minps, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_maxps, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_minss, "V4fV4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_maxss, "V4fV4fV4f", "ncV:128:", "sse")
+
+TARGET_BUILTIN(__builtin_ia32_cmpeqpd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpltpd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmplepd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpunordpd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpneqpd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpnltpd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpnlepd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpordpd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpeqsd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpltsd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmplesd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpunordsd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpneqsd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpnltsd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpnlesd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cmpordsd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_maxsd, "V2dV2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_paddsb128, "V16cV16cV16c", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_paddsw128, "V8sV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psubsb128, "V16cV16cV16c", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psubsw128, "V8sV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_paddusb128, "V16cV16cV16c", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pminsw128, "V8sV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_packsswb128, "V16cV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_packssdw128, "V8sV4iV4i", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_packuswb128, "V16cV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pmulhuw128, "V8sV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_vec_ext_v4si, "iV4iIi", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_vec_ext_v4sf, "fV4fIi", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_vec_ext_v8hi, "sV8sIi", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_vec_set_v8hi, "V8sV8ssIi", "ncV:128:", "sse2")
+
+TARGET_BUILTIN(__builtin_ia32_addsubps, "V4fV4fV4f", "ncV:128:", "sse3")
+TARGET_BUILTIN(__builtin_ia32_addsubpd, "V2dV2dV2d", "ncV:128:", "sse3")
+TARGET_BUILTIN(__builtin_ia32_haddps, "V4fV4fV4f", "ncV:128:", "sse3")
+TARGET_BUILTIN(__builtin_ia32_haddpd, "V2dV2dV2d", "ncV:128:", "sse3")
+TARGET_BUILTIN(__builtin_ia32_hsubps, "V4fV4fV4f", "ncV:128:", "sse3")
+TARGET_BUILTIN(__builtin_ia32_hsubpd, "V2dV2dV2d", "ncV:128:", "sse3")
+TARGET_BUILTIN(__builtin_ia32_phaddw128, "V8sV8sV8s", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_phaddd128, "V4iV4iV4i", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_phaddsw128, "V8sV8sV8s", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_phsubw128, "V8sV8sV8s", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_phsubd128, "V4iV4iV4i", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_phsubsw128, "V8sV8sV8s", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_pmaddubsw128, "V8sV16cV16c", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_pmulhrsw128, "V8sV8sV8s", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_pabsb128, "V16cV16c", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "ncV:128:", "ssse3")
+TARGET_BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "ncV:128:", "ssse3")
+
+TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "n", "sse")
+TARGET_HEADER_BUILTIN(_mm_setcsr, "vUi", "nh","xmmintrin.h", ALL_LANGUAGES, "sse")
+TARGET_BUILTIN(__builtin_ia32_stmxcsr, "Ui", "n", "sse")
+TARGET_HEADER_BUILTIN(_mm_getcsr, "Ui", "nh", "xmmintrin.h", ALL_LANGUAGES, "sse")
+TARGET_BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cvttss2si, "iV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "nV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "nV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_movmskps, "iV4f", "nV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_sfence, "v", "n", "sse")
+TARGET_HEADER_BUILTIN(_mm_sfence, "v", "nh", "xmmintrin.h", ALL_LANGUAGES, "sse")
+TARGET_BUILTIN(__builtin_ia32_rcpps, "V4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_rcpss, "V4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_rsqrtps, "V4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_rsqrtss, "V4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_sqrtps, "V4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_sqrtss, "V4fV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_shufps, "V4fV4fV4fIi", "ncV:128:", "sse")
+
+TARGET_BUILTIN(__builtin_ia32_maskmovdqu, "vV16cV16cc*", "nV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_movmskpd, "iV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pmovmskb128, "iV16c", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_movnti, "vi*i", "n", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pshufd, "V4iV4iIi", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pshuflw, "V8sV8sIi", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pshufhw, "V8sV8sIi", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psadbw128, "V2LLiV16cV16c", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_sqrtpd, "V2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_shufpd, "V2dV2dV2dIi", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cvttsd2si, "iV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cvtsd2ss, "V4fV4fV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_clflush, "vvC*", "n", "sse2")
+TARGET_HEADER_BUILTIN(_mm_clflush, "vvC*", "nh", "emmintrin.h", ALL_LANGUAGES, "sse2")
+TARGET_BUILTIN(__builtin_ia32_lfence, "v", "n", "sse2")
+TARGET_HEADER_BUILTIN(_mm_lfence, "v", "nh", "emmintrin.h", ALL_LANGUAGES, "sse2")
+TARGET_BUILTIN(__builtin_ia32_mfence, "v", "n", "sse2")
+TARGET_HEADER_BUILTIN(_mm_mfence, "v", "nh", "emmintrin.h", ALL_LANGUAGES, "sse2")
+TARGET_BUILTIN(__builtin_ia32_pause, "v", "n", "")
+TARGET_HEADER_BUILTIN(_mm_pause, "v", "nh", "emmintrin.h", ALL_LANGUAGES, "")
+TARGET_BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psrlw128, "V8sV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psrld128, "V4iV4iV4i", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psrlq128, "V2LLiV2LLiV2LLi", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psllw128, "V8sV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pslld128, "V4iV4iV4i", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psllq128, "V2LLiV2LLiV2LLi", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psllwi128, "V8sV8si", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pslldi128, "V4iV4ii", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psllqi128, "V2LLiV2LLii", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psrlwi128, "V8sV8si", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psrldi128, "V4iV4ii", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psrlqi128, "V2LLiV2LLii", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psrawi128, "V8sV8si", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psradi128, "V4iV4ii", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pmaddwd128, "V4iV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_pslldqi128_byteshift, "V2LLiV2LLiIi", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_psrldqi128_byteshift, "V2LLiV2LLiIi", "ncV:128:", "sse2")
+
+TARGET_BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "n", "sse3")
+TARGET_BUILTIN(__builtin_ia32_mwait, "vUiUi", "n", "sse3")
+TARGET_BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "nV:128:", "sse3")
+
+TARGET_BUILTIN(__builtin_ia32_palignr128, "V16cV16cV16cIi", "ncV:128:", "ssse3")
+
+TARGET_BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fIc", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_pblendvb128, "V16cV16cV16cV16c", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_pblendw128, "V8sV8sV8sIi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_blendpd, "V2dV2dV2dIi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_blendps, "V4fV4fV4fIi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_blendvpd, "V2dV2dV2dV2d", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_blendvps, "V4fV4fV4fV4f", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_packusdw128, "V8sV4iV4i", "ncV:128:", "sse4.1")
+
+TARGET_BUILTIN(__builtin_ia32_pmaxsb128, "V16cV16cV16c", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_pmaxsd128, "V4iV4iV4i", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_pmaxud128, "V4iV4iV4i", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_pmaxuw128, "V8sV8sV8s", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_pminsb128, "V16cV16cV16c", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_pminsd128, "V4iV4iV4i", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_pminud128, "V4iV4iV4i", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_pminuw128, "V8sV8sV8s", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_pmuldq128, "V2LLiV4iV4i", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_roundps, "V4fV4fIi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fIi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2dIi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_roundpd, "V2dV2dIi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fIc", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_dppd, "V2dV2dV2dIc", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16cIc", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_phminposuw128, "V8sV8s", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_vec_ext_v16qi, "cV16cIi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_vec_set_v16qi, "V16cV16ccIi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_vec_set_v4si, "V4iV4iiIi", "ncV:128:", "sse4.1")
// SSE 4.2
-TARGET_BUILTIN(__builtin_ia32_pcmpistrm128, "V16cV16cV16cIc", "", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_pcmpistri128, "iV16cV16cIc", "", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_pcmpestrm128, "V16cV16ciV16ciIc", "", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_pcmpestri128, "iV16ciV16ciIc","", "sse4.2")
-
-TARGET_BUILTIN(__builtin_ia32_pcmpistria128, "iV16cV16cIc","", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_pcmpistric128, "iV16cV16cIc","", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_pcmpistrio128, "iV16cV16cIc","", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_pcmpistris128, "iV16cV16cIc","", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_pcmpistriz128, "iV16cV16cIc","", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_pcmpestria128, "iV16ciV16ciIc","", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_pcmpestric128, "iV16ciV16ciIc","", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_pcmpestrio128, "iV16ciV16ciIc","", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_pcmpestris128, "iV16ciV16ciIc","", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16ciIc","", "sse4.2")
-
-TARGET_BUILTIN(__builtin_ia32_crc32qi, "UiUiUc", "", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpistrm128, "V16cV16cV16cIc", "ncV:128:", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpistri128, "iV16cV16cIc", "ncV:128:", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpestrm128, "V16cV16ciV16ciIc", "ncV:128:", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpestri128, "iV16ciV16ciIc","ncV:128:", "sse4.2")
+
+TARGET_BUILTIN(__builtin_ia32_pcmpistria128, "iV16cV16cIc","ncV:128:", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpistric128, "iV16cV16cIc","ncV:128:", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpistrio128, "iV16cV16cIc","ncV:128:", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpistris128, "iV16cV16cIc","ncV:128:", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpistriz128, "iV16cV16cIc","ncV:128:", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpestria128, "iV16ciV16ciIc","ncV:128:", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpestric128, "iV16ciV16ciIc","ncV:128:", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpestrio128, "iV16ciV16ciIc","ncV:128:", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpestris128, "iV16ciV16ciIc","ncV:128:", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16ciIc","ncV:128:", "sse4.2")
+
+TARGET_BUILTIN(__builtin_ia32_crc32qi, "UiUiUc", "nc", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "nc", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "nc", "sse4.2")
// SSE4a
-TARGET_BUILTIN(__builtin_ia32_extrqi, "V2LLiV2LLiIcIc", "", "sse4a")
-TARGET_BUILTIN(__builtin_ia32_extrq, "V2LLiV2LLiV16c", "", "sse4a")
-TARGET_BUILTIN(__builtin_ia32_insertqi, "V2LLiV2LLiV2LLiIcIc", "", "sse4a")
-TARGET_BUILTIN(__builtin_ia32_insertq, "V2LLiV2LLiV2LLi", "", "sse4a")
-TARGET_BUILTIN(__builtin_ia32_movntsd, "vd*V2d", "", "sse4a")
-TARGET_BUILTIN(__builtin_ia32_movntss, "vf*V4f", "", "sse4a")
+TARGET_BUILTIN(__builtin_ia32_extrqi, "V2LLiV2LLiIcIc", "ncV:128:", "sse4a")
+TARGET_BUILTIN(__builtin_ia32_extrq, "V2LLiV2LLiV16c", "ncV:128:", "sse4a")
+TARGET_BUILTIN(__builtin_ia32_insertqi, "V2LLiV2LLiV2LLiIcIc", "ncV:128:", "sse4a")
+TARGET_BUILTIN(__builtin_ia32_insertq, "V2LLiV2LLiV2LLi", "ncV:128:", "sse4a")
+TARGET_BUILTIN(__builtin_ia32_movntsd, "vd*V2d", "nV:128:", "sse4a")
+TARGET_BUILTIN(__builtin_ia32_movntss, "vf*V4f", "nV:128:", "sse4a")
// AES
-TARGET_BUILTIN(__builtin_ia32_aesenc128, "V2LLiV2LLiV2LLi", "", "aes")
-TARGET_BUILTIN(__builtin_ia32_aesenclast128, "V2LLiV2LLiV2LLi", "", "aes")
-TARGET_BUILTIN(__builtin_ia32_aesdec128, "V2LLiV2LLiV2LLi", "", "aes")
-TARGET_BUILTIN(__builtin_ia32_aesdeclast128, "V2LLiV2LLiV2LLi", "", "aes")
-TARGET_BUILTIN(__builtin_ia32_aesimc128, "V2LLiV2LLi", "", "aes")
-TARGET_BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLiIc", "", "aes")
+TARGET_BUILTIN(__builtin_ia32_aesenc128, "V2LLiV2LLiV2LLi", "ncV:128:", "aes")
+TARGET_BUILTIN(__builtin_ia32_aesenclast128, "V2LLiV2LLiV2LLi", "ncV:128:", "aes")
+TARGET_BUILTIN(__builtin_ia32_aesdec128, "V2LLiV2LLiV2LLi", "ncV:128:", "aes")
+TARGET_BUILTIN(__builtin_ia32_aesdeclast128, "V2LLiV2LLiV2LLi", "ncV:128:", "aes")
+TARGET_BUILTIN(__builtin_ia32_aesimc128, "V2LLiV2LLi", "ncV:128:", "aes")
+TARGET_BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLiIc", "ncV:128:", "aes")
// VAES
-TARGET_BUILTIN(__builtin_ia32_aesenc256, "V4LLiV4LLiV4LLi", "", "vaes")
-TARGET_BUILTIN(__builtin_ia32_aesenc512, "V8LLiV8LLiV8LLi", "", "avx512f,vaes")
-TARGET_BUILTIN(__builtin_ia32_aesenclast256, "V4LLiV4LLiV4LLi", "", "vaes")
-TARGET_BUILTIN(__builtin_ia32_aesenclast512, "V8LLiV8LLiV8LLi", "", "avx512f,vaes")
-TARGET_BUILTIN(__builtin_ia32_aesdec256, "V4LLiV4LLiV4LLi", "", "vaes")
-TARGET_BUILTIN(__builtin_ia32_aesdec512, "V8LLiV8LLiV8LLi", "", "avx512f,vaes")
-TARGET_BUILTIN(__builtin_ia32_aesdeclast256, "V4LLiV4LLiV4LLi", "", "vaes")
-TARGET_BUILTIN(__builtin_ia32_aesdeclast512, "V8LLiV8LLiV8LLi", "", "avx512f,vaes")
+TARGET_BUILTIN(__builtin_ia32_aesenc256, "V4LLiV4LLiV4LLi", "ncV:256:", "vaes")
+TARGET_BUILTIN(__builtin_ia32_aesenc512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f,vaes")
+TARGET_BUILTIN(__builtin_ia32_aesenclast256, "V4LLiV4LLiV4LLi", "ncV:256:", "vaes")
+TARGET_BUILTIN(__builtin_ia32_aesenclast512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f,vaes")
+TARGET_BUILTIN(__builtin_ia32_aesdec256, "V4LLiV4LLiV4LLi", "ncV:256:", "vaes")
+TARGET_BUILTIN(__builtin_ia32_aesdec512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f,vaes")
+TARGET_BUILTIN(__builtin_ia32_aesdeclast256, "V4LLiV4LLiV4LLi", "ncV:256:", "vaes")
+TARGET_BUILTIN(__builtin_ia32_aesdeclast512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f,vaes")
// GFNI
-TARGET_BUILTIN(__builtin_ia32_vgf2p8affineinvqb_v16qi, "V16cV16cV16cIc", "", "gfni")
-TARGET_BUILTIN(__builtin_ia32_vgf2p8affineinvqb_v32qi, "V32cV32cV32cIc", "", "avx,gfni")
-TARGET_BUILTIN(__builtin_ia32_vgf2p8affineinvqb_v64qi, "V64cV64cV64cIc", "", "avx512bw,gfni")
-TARGET_BUILTIN(__builtin_ia32_vgf2p8affineqb_v16qi, "V16cV16cV16cIc", "", "gfni")
-TARGET_BUILTIN(__builtin_ia32_vgf2p8affineqb_v32qi, "V32cV32cV32cIc", "", "avx,gfni")
-TARGET_BUILTIN(__builtin_ia32_vgf2p8affineqb_v64qi, "V64cV64cV64cIc", "", "avx512bw,gfni")
-TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v16qi, "V16cV16cV16c", "", "gfni")
-TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v32qi, "V32cV32cV32c", "", "avx,gfni")
-TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v64qi, "V64cV64cV64c", "", "avx512bw,gfni")
+TARGET_BUILTIN(__builtin_ia32_vgf2p8affineinvqb_v16qi, "V16cV16cV16cIc", "ncV:128:", "gfni")
+TARGET_BUILTIN(__builtin_ia32_vgf2p8affineinvqb_v32qi, "V32cV32cV32cIc", "ncV:256:", "avx,gfni")
+TARGET_BUILTIN(__builtin_ia32_vgf2p8affineinvqb_v64qi, "V64cV64cV64cIc", "ncV:512:", "avx512bw,gfni")
+TARGET_BUILTIN(__builtin_ia32_vgf2p8affineqb_v16qi, "V16cV16cV16cIc", "ncV:128:", "gfni")
+TARGET_BUILTIN(__builtin_ia32_vgf2p8affineqb_v32qi, "V32cV32cV32cIc", "ncV:256:", "avx,gfni")
+TARGET_BUILTIN(__builtin_ia32_vgf2p8affineqb_v64qi, "V64cV64cV64cIc", "ncV:512:", "avx512bw,gfni")
+TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v16qi, "V16cV16cV16c", "ncV:128:", "gfni")
+TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v32qi, "V32cV32cV32c", "ncV:256:", "avx,gfni")
+TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v64qi, "V64cV64cV64c", "ncV:512:", "avx512bw,gfni")
// CLMUL
-TARGET_BUILTIN(__builtin_ia32_pclmulqdq128, "V2LLiV2LLiV2LLiIc", "", "pclmul")
+TARGET_BUILTIN(__builtin_ia32_pclmulqdq128, "V2LLiV2LLiV2LLiIc", "ncV:128:", "pclmul")
// VPCLMULQDQ
-TARGET_BUILTIN(__builtin_ia32_pclmulqdq256, "V4LLiV4LLiV4LLiIc", "", "vpclmulqdq")
-TARGET_BUILTIN(__builtin_ia32_pclmulqdq512, "V8LLiV8LLiV8LLiIc", "", "avx512f,vpclmulqdq")
+TARGET_BUILTIN(__builtin_ia32_pclmulqdq256, "V4LLiV4LLiV4LLiIc", "ncV:256:", "vpclmulqdq")
+TARGET_BUILTIN(__builtin_ia32_pclmulqdq512, "V8LLiV8LLiV8LLiIc", "ncV:512:", "avx512f,vpclmulqdq")
// AVX
-TARGET_BUILTIN(__builtin_ia32_addsubpd256, "V4dV4dV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_addsubps256, "V8fV8fV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_haddpd256, "V4dV4dV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_hsubps256, "V8fV8fV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_hsubpd256, "V4dV4dV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_haddps256, "V8fV8fV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_maxpd256, "V4dV4dV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_maxps256, "V8fV8fV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_minpd256, "V4dV4dV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_minps256, "V8fV8fV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2LLi", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarps, "V4fV4fV4i", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4LLi", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarps256, "V8fV8fV8i", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_blendvpd256, "V4dV4dV4dV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_blendvps256, "V8fV8fV8fV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fIc", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cmppd256, "V4dV4dV4dIc", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fIc", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cvtdq2ps256, "V8fV8i", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2ps256, "V4fV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cvtps2dq256, "V8iV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2dq256, "V4iV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2dq256, "V4iV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_cvttps2dq256, "V8iV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vperm2f128_pd256, "V4dV4dV4dIc", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vperm2f128_ps256, "V8fV8fV8fIc", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vperm2f128_si256, "V8iV8iV8iIc", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_sqrtpd256, "V4dV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_sqrtps256, "V8fV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_rsqrtps256, "V8fV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_rcpps256, "V8fV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_roundpd256, "V4dV4dIi", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_roundps256, "V8fV8fIi", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vtestzpd, "iV2dV2d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vtestcpd, "iV2dV2d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vtestnzcpd, "iV2dV2d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vtestzps, "iV4fV4f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vtestcps, "iV4fV4f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vtestnzcps, "iV4fV4f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vtestzpd256, "iV4dV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vtestcpd256, "iV4dV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vtestnzcpd256, "iV4dV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vtestzps256, "iV8fV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vtestcps256, "iV8fV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vtestnzcps256, "iV8fV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_ptestz256, "iV4LLiV4LLi", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_ptestc256, "iV4LLiV4LLi", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_ptestnzc256, "iV4LLiV4LLi", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_movmskpd256, "iV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_movmskps256, "iV8f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vzeroall, "v", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vzeroupper, "v", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vbroadcastf128_pd256, "V4dV2dC*", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_vbroadcastf128_ps256, "V8fV4fC*", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_lddqu256, "V32ccC*", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_maskloadpd, "V2dV2dC*V2LLi", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_maskloadps, "V4fV4fC*V4i", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_maskloadpd256, "V4dV4dC*V4LLi", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_maskloadps256, "V8fV8fC*V8i", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_maskstorepd, "vV2d*V2LLiV2d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_maskstoreps, "vV4f*V4iV4f", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_maskstorepd256, "vV4d*V4LLiV4d", "", "avx")
-TARGET_BUILTIN(__builtin_ia32_maskstoreps256, "vV8f*V8iV8f", "", "avx")
+TARGET_BUILTIN(__builtin_ia32_addsubpd256, "V4dV4dV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_addsubps256, "V8fV8fV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_haddpd256, "V4dV4dV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_hsubps256, "V8fV8fV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_hsubpd256, "V4dV4dV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_haddps256, "V8fV8fV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_maxpd256, "V4dV4dV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_maxps256, "V8fV8fV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_minpd256, "V4dV4dV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_minps256, "V8fV8fV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2LLi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vpermilvarps, "V4fV4fV4i", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4LLi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vpermilvarps256, "V8fV8fV8i", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_blendpd256, "V4dV4dV4dIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_blendps256, "V8fV8fV8fIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_blendvpd256, "V4dV4dV4dV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_blendvps256, "V8fV8fV8fV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_shufpd256, "V4dV4dV4dIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_shufps256, "V8fV8fV8fIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fIc", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "ncV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_cmppd256, "V4dV4dV4dIc", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "ncV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fIc", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "ncV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "ncV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vextractf128_pd256, "V2dV4dIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vextractf128_ps256, "V4fV8fIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vextractf128_si256, "V4iV8iIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2ps256, "V4fV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_cvtps2dq256, "V8iV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2dq256, "V4iV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2dq256, "V4iV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_cvttps2dq256, "V8iV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vperm2f128_pd256, "V4dV4dV4dIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vperm2f128_ps256, "V8fV8fV8fIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vperm2f128_si256, "V8iV8iV8iIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vpermilpd, "V2dV2dIi", "ncV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vpermilps, "V4fV4fIi", "ncV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vpermilpd256, "V4dV4dIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vpermilps256, "V8fV8fIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vinsertf128_pd256, "V4dV4dV2dIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vinsertf128_ps256, "V8fV8fV4fIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vinsertf128_si256, "V8iV8iV4iIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_sqrtpd256, "V4dV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_sqrtps256, "V8fV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_rsqrtps256, "V8fV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_rcpps256, "V8fV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_roundpd256, "V4dV4dIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_roundps256, "V8fV8fIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vtestzpd, "iV2dV2d", "ncV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vtestcpd, "iV2dV2d", "ncV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vtestnzcpd, "iV2dV2d", "ncV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vtestzps, "iV4fV4f", "ncV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vtestcps, "iV4fV4f", "ncV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vtestnzcps, "iV4fV4f", "ncV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vtestzpd256, "iV4dV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vtestcpd256, "iV4dV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vtestnzcpd256, "iV4dV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vtestzps256, "iV8fV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vtestcps256, "iV8fV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vtestnzcps256, "iV8fV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_ptestz256, "iV4LLiV4LLi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_ptestc256, "iV4LLiV4LLi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_ptestnzc256, "iV4LLiV4LLi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_movmskpd256, "iV4d", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_movmskps256, "iV8f", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vzeroall, "v", "n", "avx")
+TARGET_BUILTIN(__builtin_ia32_vzeroupper, "v", "n", "avx")
+TARGET_BUILTIN(__builtin_ia32_lddqu256, "V32ccC*", "nV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_maskloadpd, "V2dV2dC*V2LLi", "nV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_maskloadps, "V4fV4fC*V4i", "nV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_maskloadpd256, "V4dV4dC*V4LLi", "nV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_maskloadps256, "V8fV8fC*V8i", "nV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_maskstorepd, "vV2d*V2LLiV2d", "nV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_maskstoreps, "vV4f*V4iV4f", "nV:128:", "avx")
+TARGET_BUILTIN(__builtin_ia32_maskstorepd256, "vV4d*V4LLiV4d", "nV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_maskstoreps256, "vV8f*V8iV8f", "nV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vec_ext_v32qi, "cV32cIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vec_ext_v16hi, "sV16sIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vec_ext_v8si, "iV8iIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vec_set_v32qi, "V32cV32ccIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vec_set_v16hi, "V16sV16ssIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vec_set_v8si, "V8iV8iiIi", "ncV:256:", "avx")
// AVX2
-TARGET_BUILTIN(__builtin_ia32_mpsadbw256, "V32cV32cV32cIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pabsb256, "V32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pabsw256, "V16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pabsd256, "V8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_packsswb256, "V32cV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_packssdw256, "V16sV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_packuswb256, "V32cV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_packusdw256, "V16sV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_paddsb256, "V32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_paddsw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psubsb256, "V32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psubsw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_paddusb256, "V32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_paddusw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psubusb256, "V32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psubusw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIi", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_phaddd256, "V8iV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_phaddsw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_phsubw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_phsubd256, "V8iV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_phsubsw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmaddubsw256, "V16sV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmaddwd256, "V8iV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmaxub256, "V32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmaxuw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmaxud256, "V8iV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmaxsb256, "V32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmaxsw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmaxsd256, "V8iV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pminub256, "V32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pminuw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pminud256, "V8iV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pminsb256, "V32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pminsw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pminsd256, "V8iV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmovmskb256, "iV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmuldq256, "V4LLiV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmulhrsw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmulhuw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmulhw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pmuludq256, "V4LLiV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psadbw256, "V4LLiV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pshufb256, "V32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psignb256, "V32cV32cV32c", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psignw256, "V16sV16sV16s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psignd256, "V8iV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psllwi256, "V16sV16si", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psllw256, "V16sV16sV8s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pslldi256, "V8iV8ii", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_pslld256, "V8iV8iV4i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psllqi256, "V4LLiV4LLii", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psllq256, "V4LLiV4LLiV2LLi", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrawi256, "V16sV16si", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psraw256, "V16sV16sV8s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psradi256, "V8iV8ii", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrad256, "V8iV8iV4i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrlwi256, "V16sV16si", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrlw256, "V16sV16sV8s", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrldi256, "V8iV8ii", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrld256, "V8iV8iV4i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrlqi256, "V4LLiV4LLii", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrlq256, "V4LLiV4LLiV2LLi", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_permvarsi256, "V8iV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_permvarsf256, "V8fV8fV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_permti256, "V4LLiV4LLiV4LLiIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_maskloadd256, "V8iV8iC*V8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_maskloadq256, "V4LLiV4LLiC*V4LLi", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_maskloadd, "V4iV4iC*V4i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_maskloadq, "V2LLiV2LLiC*V2LLi", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_maskstored256, "vV8i*V8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_maskstoreq256, "vV4LLi*V4LLiV4LLi", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_maskstored, "vV4i*V4iV4i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_maskstoreq, "vV2LLi*V2LLiV2LLi", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psllv8si, "V8iV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psllv4si, "V4iV4iV4i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psllv4di, "V4LLiV4LLiV4LLi", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psllv2di, "V2LLiV2LLiV2LLi", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrav8si, "V8iV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrav4si, "V4iV4iV4i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrlv8si, "V8iV8iV8i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrlv4si, "V4iV4iV4i", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrlv4di, "V4LLiV4LLiV4LLi", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psrlv2di, "V2LLiV2LLiV2LLi", "", "avx2")
+TARGET_BUILTIN(__builtin_ia32_mpsadbw256, "V32cV32cV32cIc", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pabsb256, "V32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pabsw256, "V16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pabsd256, "V8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_packsswb256, "V32cV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_packssdw256, "V16sV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_packuswb256, "V32cV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_packusdw256, "V16sV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_paddsb256, "V32cV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_paddsw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psubsb256, "V32cV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psubsw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_paddusb256, "V32cV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_paddusw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psubusb256, "V32cV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psubusw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pblendw256, "V16sV16sV16sIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_phaddd256, "V8iV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_phaddsw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_phsubw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_phsubd256, "V8iV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_phsubsw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmaddubsw256, "V16sV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmaddwd256, "V8iV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmaxub256, "V32cV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmaxuw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmaxud256, "V8iV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmaxsb256, "V32cV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmaxsw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmaxsd256, "V8iV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pminub256, "V32cV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pminuw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pminud256, "V8iV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pminsb256, "V32cV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pminsw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pminsd256, "V8iV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmovmskb256, "iV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmuldq256, "V4LLiV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmulhrsw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmulhuw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmulhw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pmuludq256, "V4LLiV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psadbw256, "V4LLiV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pshufb256, "V32cV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pshufd256, "V8iV8iIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pshuflw256, "V16sV16sIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pshufhw256, "V16sV16sIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psignb256, "V32cV32cV32c", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psignw256, "V16sV16sV16s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psignd256, "V8iV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psllwi256, "V16sV16si", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psllw256, "V16sV16sV8s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pslldqi256_byteshift, "V4LLiV4LLiIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pslldi256, "V8iV8ii", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pslld256, "V8iV8iV4i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psllqi256, "V4LLiV4LLii", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psllq256, "V4LLiV4LLiV2LLi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrawi256, "V16sV16si", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psraw256, "V16sV16sV8s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psradi256, "V8iV8ii", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrad256, "V8iV8iV4i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrldqi256_byteshift, "V4LLiV4LLiIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrlwi256, "V16sV16si", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrlw256, "V16sV16sV8s", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrldi256, "V8iV8ii", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrld256, "V8iV8iV4i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrlqi256, "V4LLiV4LLii", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrlq256, "V4LLiV4LLiV2LLi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pblendd128, "V4iV4iV4iIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_pblendd256, "V8iV8iV8iIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_permvarsi256, "V8iV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_permdf256, "V4dV4dIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_permvarsf256, "V8fV8fV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_permti256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_permdi256, "V4LLiV4LLiIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_extract128i256, "V2LLiV4LLiIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_insert128i256, "V4LLiV4LLiV2LLiIi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_maskloadd256, "V8iV8iC*V8i", "nV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_maskloadq256, "V4LLiV4LLiC*V4LLi", "nV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_maskloadd, "V4iV4iC*V4i", "nV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_maskloadq, "V2LLiV2LLiC*V2LLi", "nV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_maskstored256, "vV8i*V8iV8i", "nV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_maskstoreq256, "vV4LLi*V4LLiV4LLi", "nV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_maskstored, "vV4i*V4iV4i", "nV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_maskstoreq, "vV2LLi*V2LLiV2LLi", "nV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psllv8si, "V8iV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psllv4si, "V4iV4iV4i", "ncV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psllv4di, "V4LLiV4LLiV4LLi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psllv2di, "V2LLiV2LLiV2LLi", "ncV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrav8si, "V8iV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrav4si, "V4iV4iV4i", "ncV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrlv8si, "V8iV8iV8i", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrlv4si, "V4iV4iV4i", "ncV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrlv4di, "V4LLiV4LLiV4LLi", "ncV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_psrlv2di, "V2LLiV2LLiV2LLi", "ncV:128:", "avx2")
// GATHER
-TARGET_BUILTIN(__builtin_ia32_gatherd_pd, "V2dV2ddC*V4iV2dIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherd_pd256, "V4dV4ddC*V4iV4dIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherq_pd, "V2dV2ddC*V2LLiV2dIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherq_pd256, "V4dV4ddC*V4LLiV4dIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherd_ps, "V4fV4ffC*V4iV4fIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherd_ps256, "V8fV8ffC*V8iV8fIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherq_ps, "V4fV4ffC*V2LLiV4fIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherq_ps256, "V4fV4ffC*V4LLiV4fIc", "", "avx2")
-
-TARGET_BUILTIN(__builtin_ia32_gatherd_q, "V2LLiV2LLiLLiC*V4iV2LLiIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherd_q256, "V4LLiV4LLiLLiC*V4iV4LLiIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherq_q, "V2LLiV2LLiLLiC*V2LLiV2LLiIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherq_q256, "V4LLiV4LLiLLiC*V4LLiV4LLiIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherd_d, "V4iV4iiC*V4iV4iIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherd_d256, "V8iV8iiC*V8iV8iIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherq_d, "V4iV4iiC*V2LLiV4iIc", "", "avx2")
-TARGET_BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iiC*V4LLiV4iIc", "", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherd_pd, "V2dV2ddC*V4iV2dIc", "nV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherd_pd256, "V4dV4ddC*V4iV4dIc", "nV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherq_pd, "V2dV2ddC*V2LLiV2dIc", "nV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherq_pd256, "V4dV4ddC*V4LLiV4dIc", "nV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherd_ps, "V4fV4ffC*V4iV4fIc", "nV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherd_ps256, "V8fV8ffC*V8iV8fIc", "nV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherq_ps, "V4fV4ffC*V2LLiV4fIc", "nV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherq_ps256, "V4fV4ffC*V4LLiV4fIc", "nV:256:", "avx2")
+
+TARGET_BUILTIN(__builtin_ia32_gatherd_q, "V2LLiV2LLiLLiC*V4iV2LLiIc", "nV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherd_q256, "V4LLiV4LLiLLiC*V4iV4LLiIc", "nV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherq_q, "V2LLiV2LLiLLiC*V2LLiV2LLiIc", "nV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherq_q256, "V4LLiV4LLiLLiC*V4LLiV4LLiIc", "nV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherd_d, "V4iV4iiC*V4iV4iIc", "nV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherd_d256, "V8iV8iiC*V8iV8iIc", "nV:256:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherq_d, "V4iV4iiC*V2LLiV4iIc", "nV:128:", "avx2")
+TARGET_BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iiC*V4LLiV4iIc", "nV:256:", "avx2")
// F16C
-TARGET_BUILTIN(__builtin_ia32_vcvtps2ph, "V8sV4fIi", "", "f16c")
-TARGET_BUILTIN(__builtin_ia32_vcvtps2ph256, "V8sV8fIi", "", "f16c")
-TARGET_BUILTIN(__builtin_ia32_vcvtph2ps, "V4fV8s", "", "f16c")
-TARGET_BUILTIN(__builtin_ia32_vcvtph2ps256, "V8fV8s", "", "f16c")
+TARGET_BUILTIN(__builtin_ia32_vcvtps2ph, "V8sV4fIi", "ncV:128:", "f16c")
+TARGET_BUILTIN(__builtin_ia32_vcvtps2ph256, "V8sV8fIi", "ncV:256:", "f16c")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2ps, "V4fV8s", "ncV:128:", "f16c")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2ps256, "V8fV8s", "ncV:256:", "f16c")
// RDRAND
-TARGET_BUILTIN(__builtin_ia32_rdrand16_step, "UiUs*", "", "rdrnd")
-TARGET_BUILTIN(__builtin_ia32_rdrand32_step, "UiUi*", "", "rdrnd")
-TARGET_BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "", "rdrnd")
-
-// FSGSBASE
-TARGET_BUILTIN(__builtin_ia32_rdfsbase32, "Ui", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_rdgsbase32, "Ui", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_wrfsbase32, "vUi", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_wrgsbase32, "vUi", "", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_rdrand16_step, "UiUs*", "n", "rdrnd")
+TARGET_BUILTIN(__builtin_ia32_rdrand32_step, "UiUi*", "n", "rdrnd")
// FXSR
-TARGET_BUILTIN(__builtin_ia32_fxrstor, "vv*", "", "fxsr")
-TARGET_BUILTIN(__builtin_ia32_fxsave, "vv*", "", "fxsr")
+TARGET_BUILTIN(__builtin_ia32_fxrstor, "vv*", "n", "fxsr")
+TARGET_BUILTIN(__builtin_ia32_fxsave, "vv*", "n", "fxsr")
// XSAVE
-TARGET_BUILTIN(__builtin_ia32_xsave, "vv*ULLi", "", "xsave")
-TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*ULLi", "", "xsave")
-TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*ULLi", "", "xsaveopt")
-TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "", "xsaves")
-TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "", "xsavec")
-TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "", "xsaves")
+TARGET_BUILTIN(__builtin_ia32_xsave, "vv*ULLi", "n", "xsave")
+TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*ULLi", "n", "xsave")
+TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*ULLi", "n", "xsaveopt")
+TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "n", "xsaves")
+TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "n", "xsavec")
+TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "n", "xsaves")
// SHSTK
-TARGET_BUILTIN(__builtin_ia32_incsspd, "vUi", "u", "shstk")
-TARGET_BUILTIN(__builtin_ia32_rdsspd, "UiUi", "Un", "shstk")
-TARGET_BUILTIN(__builtin_ia32_saveprevssp, "v", "", "shstk")
-TARGET_BUILTIN(__builtin_ia32_rstorssp, "vv*", "", "shstk")
-TARGET_BUILTIN(__builtin_ia32_wrssd, "vUiv*", "", "shstk")
-TARGET_BUILTIN(__builtin_ia32_wrussd, "vUiv*", "", "shstk")
-TARGET_BUILTIN(__builtin_ia32_setssbsy, "v", "", "shstk")
-TARGET_BUILTIN(__builtin_ia32_clrssbsy, "vv*", "", "shstk")
+TARGET_BUILTIN(__builtin_ia32_incsspd, "vUi", "n", "shstk")
+TARGET_BUILTIN(__builtin_ia32_rdsspd, "UiUi", "n", "shstk")
+TARGET_BUILTIN(__builtin_ia32_saveprevssp, "v", "n", "shstk")
+TARGET_BUILTIN(__builtin_ia32_rstorssp, "vv*", "n", "shstk")
+TARGET_BUILTIN(__builtin_ia32_wrssd, "vUiv*", "n", "shstk")
+TARGET_BUILTIN(__builtin_ia32_wrussd, "vUiv*", "n", "shstk")
+TARGET_BUILTIN(__builtin_ia32_setssbsy, "v", "n", "shstk")
+TARGET_BUILTIN(__builtin_ia32_clrssbsy, "vv*", "n", "shstk")
//CLFLUSHOPT
-TARGET_BUILTIN(__builtin_ia32_clflushopt, "vvC*", "", "clflushopt")
+TARGET_BUILTIN(__builtin_ia32_clflushopt, "vvC*", "n", "clflushopt")
//CLWB
-TARGET_BUILTIN(__builtin_ia32_clwb, "vvC*", "", "clwb")
+TARGET_BUILTIN(__builtin_ia32_clwb, "vvC*", "n", "clwb")
+
+//WB[NO]INVD
+TARGET_BUILTIN(__builtin_ia32_wbinvd, "v", "n", "")
+TARGET_BUILTIN(__builtin_ia32_wbnoinvd, "v", "n", "wbnoinvd")
// ADX
-TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "", "adx")
-TARGET_BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "", "")
-TARGET_BUILTIN(__builtin_ia32_subborrow_u32, "UcUcUiUiUi*", "", "")
+TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "n", "adx")
+TARGET_BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "n", "")
+TARGET_BUILTIN(__builtin_ia32_subborrow_u32, "UcUcUiUiUi*", "n", "")
// RDSEED
-TARGET_BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "", "rdseed")
-TARGET_BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "", "rdseed")
+TARGET_BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "n", "rdseed")
+TARGET_BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "n", "rdseed")
// BMI
-TARGET_BUILTIN(__builtin_ia32_bextr_u32, "UiUiUi", "", "bmi")
+TARGET_BUILTIN(__builtin_ia32_bextr_u32, "UiUiUi", "nc", "bmi")
// BMI2
-TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "", "bmi2")
+TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "nc", "bmi2")
+TARGET_BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "nc", "bmi2")
+TARGET_BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "nc", "bmi2")
// TBM
-TARGET_BUILTIN(__builtin_ia32_bextri_u32, "UiUiIUi", "", "tbm")
+TARGET_BUILTIN(__builtin_ia32_bextri_u32, "UiUiIUi", "nc", "tbm")
// LWP
-TARGET_BUILTIN(__builtin_ia32_llwpcb, "vv*", "", "lwp")
-TARGET_BUILTIN(__builtin_ia32_slwpcb, "v*", "", "lwp")
-TARGET_BUILTIN(__builtin_ia32_lwpins32, "UcUiUiUi", "", "lwp")
-TARGET_BUILTIN(__builtin_ia32_lwpval32, "vUiUiUi", "", "lwp")
+TARGET_BUILTIN(__builtin_ia32_llwpcb, "vv*", "n", "lwp")
+TARGET_BUILTIN(__builtin_ia32_slwpcb, "v*", "n", "lwp")
+TARGET_BUILTIN(__builtin_ia32_lwpins32, "UcUiUiUi", "n", "lwp")
+TARGET_BUILTIN(__builtin_ia32_lwpval32, "vUiUiUi", "n", "lwp")
// SHA
-TARGET_BUILTIN(__builtin_ia32_sha1rnds4, "V4iV4iV4iIc", "", "sha")
-TARGET_BUILTIN(__builtin_ia32_sha1nexte, "V4iV4iV4i", "", "sha")
-TARGET_BUILTIN(__builtin_ia32_sha1msg1, "V4iV4iV4i", "", "sha")
-TARGET_BUILTIN(__builtin_ia32_sha1msg2, "V4iV4iV4i", "", "sha")
-TARGET_BUILTIN(__builtin_ia32_sha256rnds2, "V4iV4iV4iV4i", "", "sha")
-TARGET_BUILTIN(__builtin_ia32_sha256msg1, "V4iV4iV4i", "", "sha")
-TARGET_BUILTIN(__builtin_ia32_sha256msg2, "V4iV4iV4i", "", "sha")
+TARGET_BUILTIN(__builtin_ia32_sha1rnds4, "V4iV4iV4iIc", "ncV:128:", "sha")
+TARGET_BUILTIN(__builtin_ia32_sha1nexte, "V4iV4iV4i", "ncV:128:", "sha")
+TARGET_BUILTIN(__builtin_ia32_sha1msg1, "V4iV4iV4i", "ncV:128:", "sha")
+TARGET_BUILTIN(__builtin_ia32_sha1msg2, "V4iV4iV4i", "ncV:128:", "sha")
+TARGET_BUILTIN(__builtin_ia32_sha256rnds2, "V4iV4iV4iV4i", "ncV:128:", "sha")
+TARGET_BUILTIN(__builtin_ia32_sha256msg1, "V4iV4iV4i", "ncV:128:", "sha")
+TARGET_BUILTIN(__builtin_ia32_sha256msg2, "V4iV4iV4i", "ncV:128:", "sha")
// FMA
-TARGET_BUILTIN(__builtin_ia32_vfmaddps, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddss3, "V4fV4fV4fV4f", "", "fma")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsd3, "V2dV2dV2dV2d", "", "fma")
-TARGET_BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "", "fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsd, "V2dV2dV2dV2d", "", "fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps, "V4fV4fV4fV4f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd, "V2dV2dV2dV2d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd256, "V4dV4dV4dV4d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddpd256, "V4dV4dV4dV4d", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256, "V8fV8fV8fV8f", "", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256, "V4dV4dV4dV4d", "", "fma|fma4")
-
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd128_mask3, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd128_maskz, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd256_mask3, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd256_maskz, "V4dV4dV4dV4dUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_mask3, "V8dV8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_maskz, "V8dV8dV8dV8dUcIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_vfmaddps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddps128_mask3, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddps128_maskz, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddps256_mask3, "V8fV8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddps256_maskz, "V8fV8fV8fV8fUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vfmaddps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddps512_mask3, "V16fV16fV16fV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddps512_maskz, "V16fV16fV16fV16fUsIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd128_mask3, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd128_maskz, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256_mask3, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256_maskz, "V4dV4dV4dV4dUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_mask3, "V8dV8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_maskz, "V8dV8dV8dV8dUcIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps128_mask3, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps128_maskz, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256_mask3, "V8fV8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256_maskz, "V8fV8fV8fV8fUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_mask3, "V16fV16fV16fV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_maskz, "V16fV16fV16fV16fUsIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_vfmsubpd128_mask3, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmsubpd256_mask3, "V4dV4dV4dV4dUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vfmsubpd512_mask3, "V8dV8dV8dV8dUcIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_vfmsubps128_mask3, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmsubps256_mask3, "V8fV8fV8fV8fUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vfmsubps512_mask3, "V16fV16fV16fV16fUsIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd128_mask3, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd256_mask3, "V4dV4dV4dV4dUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd512_mask3, "V8dV8dV8dV8dUcIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddps128_mask3, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddps256_mask3, "V8fV8fV8fV8fUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddps512_mask3, "V16fV16fV16fV16fUsIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_vfnmaddpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vfnmaddpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_vfnmaddps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfnmaddps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vfnmaddps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_vfnmsubpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubpd128_mask3, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubpd256_mask3, "V4dV4dV4dV4dUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vfnmsubpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubpd512_mask3, "V8dV8dV8dV8dUcIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_vfnmsubps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubps128_mask3, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubps256_mask3, "V8fV8fV8fV8fUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vfnmsubps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubps512_mask3, "V16fV16fV16fV16fUsIi", "", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddps, "V4fV4fV4fV4f", "ncV:128:", "fma|fma4")
+TARGET_BUILTIN(__builtin_ia32_vfmaddpd, "V2dV2dV2dV2d", "ncV:128:", "fma|fma4")
+TARGET_BUILTIN(__builtin_ia32_vfmaddss3, "V4fV4fV4fV4f", "ncV:128:", "fma")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsd3, "V2dV2dV2dV2d", "ncV:128:", "fma")
+TARGET_BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "ncV:128:", "fma4")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsd, "V2dV2dV2dV2d", "ncV:128:", "fma4")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubps, "V4fV4fV4fV4f", "ncV:128:", "fma|fma4")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd, "V2dV2dV2dV2d", "ncV:128:", "fma|fma4")
+TARGET_BUILTIN(__builtin_ia32_vfmaddps256, "V8fV8fV8fV8f", "ncV:256:", "fma|fma4")
+TARGET_BUILTIN(__builtin_ia32_vfmaddpd256, "V4dV4dV4dV4d", "ncV:256:", "fma|fma4")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256, "V8fV8fV8fV8f", "ncV:256:", "fma|fma4")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256, "V4dV4dV4dV4d", "ncV:256:", "fma|fma4")
+
+TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_mask, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_maskz, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_mask3, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmsubpd512_mask3, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddps512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddps512_maskz, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddps512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmsubps512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_mask, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_maskz, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_mask3, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd512_mask3, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_maskz, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmsubaddps512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
// XOP
-TARGET_BUILTIN(__builtin_ia32_vpmacssww, "V8sV8sV8sV8s", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpmacsww, "V8sV8sV8sV8s", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpmacsswd, "V4iV8sV8sV4i", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpmacswd, "V4iV8sV8sV4i", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpmacssdd, "V4iV4iV4iV4i", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpmacsdd, "V4iV4iV4iV4i", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpmacssdql, "V2LLiV4iV4iV2LLi", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpmacsdql, "V2LLiV4iV4iV2LLi", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpmacssdqh, "V2LLiV4iV4iV2LLi", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpmacsdqh, "V2LLiV4iV4iV2LLi", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpmadcsswd, "V4iV8sV8sV4i", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpmadcswd, "V4iV8sV8sV4i", "", "xop")
-
-TARGET_BUILTIN(__builtin_ia32_vphaddbw, "V8sV16c", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphaddbd, "V4iV16c", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphaddbq, "V2LLiV16c", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphaddwd, "V4iV8s", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphaddwq, "V2LLiV8s", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphadddq, "V2LLiV4i", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphaddubw, "V8sV16c", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphaddubd, "V4iV16c", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphaddubq, "V2LLiV16c", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphadduwd, "V4iV8s", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphadduwq, "V2LLiV8s", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphaddudq, "V2LLiV4i", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphsubbw, "V8sV16c", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphsubwd, "V4iV8s", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vphsubdq, "V2LLiV4i", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpperm, "V16cV16cV16cV16c", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vprotb, "V16cV16cV16c", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vprotw, "V8sV8sV8s", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vprotd, "V4iV4iV4i", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vprotq, "V2LLiV2LLiV2LLi", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vprotbi, "V16cV16cIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vprotwi, "V8sV8sIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vprotdi, "V4iV4iIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vprotqi, "V2LLiV2LLiIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpshlb, "V16cV16cV16c", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpshlw, "V8sV8sV8s", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpshld, "V4iV4iV4i", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpshlq, "V2LLiV2LLiV2LLi", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpshab, "V16cV16cV16c", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpshaw, "V8sV8sV8s", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpshad, "V4iV4iV4i", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpshaq, "V2LLiV2LLiV2LLi", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpcomub, "V16cV16cV16cIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpcomuw, "V8sV8sV8sIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpcomud, "V4iV4iV4iIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpcomuq, "V2LLiV2LLiV2LLiIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpcomb, "V16cV16cV16cIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpcomw, "V8sV8sV8sIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpcomd, "V4iV4iV4iIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpcomq, "V2LLiV2LLiV2LLiIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpermil2pd, "V2dV2dV2dV2LLiIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpermil2pd256, "V4dV4dV4dV4LLiIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpermil2ps, "V4fV4fV4fV4iIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vpermil2ps256, "V8fV8fV8fV8iIc", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vfrczss, "V4fV4f", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vfrczsd, "V2dV2d", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vfrczps, "V4fV4f", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vfrczpd, "V2dV2d", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vfrczps256, "V8fV8f", "", "xop")
-TARGET_BUILTIN(__builtin_ia32_vfrczpd256, "V4dV4d", "", "xop")
-
-TARGET_BUILTIN(__builtin_ia32_xbegin, "i", "", "rtm")
-TARGET_BUILTIN(__builtin_ia32_xend, "v", "", "rtm")
-TARGET_BUILTIN(__builtin_ia32_xabort, "vIc", "", "rtm")
-TARGET_BUILTIN(__builtin_ia32_xtest, "i", "", "rtm")
+TARGET_BUILTIN(__builtin_ia32_vpmacssww, "V8sV8sV8sV8s", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpmacsww, "V8sV8sV8sV8s", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpmacsswd, "V4iV8sV8sV4i", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpmacswd, "V4iV8sV8sV4i", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpmacssdd, "V4iV4iV4iV4i", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpmacsdd, "V4iV4iV4iV4i", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpmacssdql, "V2LLiV4iV4iV2LLi", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpmacsdql, "V2LLiV4iV4iV2LLi", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpmacssdqh, "V2LLiV4iV4iV2LLi", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpmacsdqh, "V2LLiV4iV4iV2LLi", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpmadcsswd, "V4iV8sV8sV4i", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpmadcswd, "V4iV8sV8sV4i", "ncV:128:", "xop")
+
+TARGET_BUILTIN(__builtin_ia32_vphaddbw, "V8sV16c", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphaddbd, "V4iV16c", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphaddbq, "V2LLiV16c", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphaddwd, "V4iV8s", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphaddwq, "V2LLiV8s", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphadddq, "V2LLiV4i", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphaddubw, "V8sV16c", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphaddubd, "V4iV16c", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphaddubq, "V2LLiV16c", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphadduwd, "V4iV8s", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphadduwq, "V2LLiV8s", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphaddudq, "V2LLiV4i", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphsubbw, "V8sV16c", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphsubwd, "V4iV8s", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vphsubdq, "V2LLiV4i", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpperm, "V16cV16cV16cV16c", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vprotb, "V16cV16cV16c", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vprotw, "V8sV8sV8s", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vprotd, "V4iV4iV4i", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vprotq, "V2LLiV2LLiV2LLi", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vprotbi, "V16cV16cIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vprotwi, "V8sV8sIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vprotdi, "V4iV4iIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vprotqi, "V2LLiV2LLiIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpshlb, "V16cV16cV16c", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpshlw, "V8sV8sV8s", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpshld, "V4iV4iV4i", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpshlq, "V2LLiV2LLiV2LLi", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpshab, "V16cV16cV16c", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpshaw, "V8sV8sV8s", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpshad, "V4iV4iV4i", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpshaq, "V2LLiV2LLiV2LLi", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpcomub, "V16cV16cV16cIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpcomuw, "V8sV8sV8sIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpcomud, "V4iV4iV4iIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpcomuq, "V2LLiV2LLiV2LLiIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpcomb, "V16cV16cV16cIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpcomw, "V8sV8sV8sIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpcomd, "V4iV4iV4iIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpcomq, "V2LLiV2LLiV2LLiIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpermil2pd, "V2dV2dV2dV2LLiIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpermil2pd256, "V4dV4dV4dV4LLiIc", "ncV:256:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpermil2ps, "V4fV4fV4fV4iIc", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vpermil2ps256, "V8fV8fV8fV8iIc", "ncV:256:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vfrczss, "V4fV4f", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vfrczsd, "V2dV2d", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vfrczps, "V4fV4f", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vfrczpd, "V2dV2d", "ncV:128:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vfrczps256, "V8fV8f", "ncV:256:", "xop")
+TARGET_BUILTIN(__builtin_ia32_vfrczpd256, "V4dV4d", "ncV:256:", "xop")
+
+TARGET_BUILTIN(__builtin_ia32_xbegin, "i", "n", "rtm")
+TARGET_BUILTIN(__builtin_ia32_xend, "v", "n", "rtm")
+TARGET_BUILTIN(__builtin_ia32_xabort, "vIc", "n", "rtm")
+TARGET_BUILTIN(__builtin_ia32_xtest, "i", "n", "rtm")
BUILTIN(__builtin_ia32_rdpmc, "ULLii", "")
BUILTIN(__builtin_ia32_rdtsc, "ULLi", "")
BUILTIN(__rdtsc, "ULLi", "")
BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "")
+
+TARGET_BUILTIN(__builtin_ia32_rdpid, "Ui", "n", "rdpid")
+
// PKU
-TARGET_BUILTIN(__builtin_ia32_rdpkru, "Ui", "", "pku")
-TARGET_BUILTIN(__builtin_ia32_wrpkru, "vUi", "", "pku")
+TARGET_BUILTIN(__builtin_ia32_rdpkru, "Ui", "n", "pku")
+TARGET_BUILTIN(__builtin_ia32_wrpkru, "vUi", "n", "pku")
// AVX-512
-TARGET_BUILTIN(__builtin_ia32_sqrtpd512_mask, "V8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_sqrtps512_mask, "V16fV16fV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14sd_mask, "V2dV2dV2dV2dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14ss_mask, "V4fV4fV4fV4fUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14pd512_mask, "V8dV8dV8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14ps512_mask, "V16fV16fV16fUs", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_rsqrt28sd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rsqrt28ss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rsqrt28pd_mask, "V8dV8dV8dUcIi", "", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rsqrt28ps_mask, "V16fV16fV16fUsIi", "", "avx512er")
-
-TARGET_BUILTIN(__builtin_ia32_rcp14sd_mask, "V2dV2dV2dV2dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rcp14ss_mask, "V4fV4fV4fV4fUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rcp14pd512_mask, "V8dV8dV8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rcp14ps512_mask, "V16fV16fV16fUs", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_rcp28sd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rcp28ss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rcp28pd_mask, "V8dV8dV8dUcIi", "", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rcp28ps_mask, "V16fV16fV16fUsIi", "", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_exp2pd_mask, "V8dV8dV8dUcIi", "", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_exp2ps_mask, "V16fV16fV16fUsIi", "", "avx512er")
-
-TARGET_BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUcIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cmpps256_mask, "UcV8fV8fIiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cmpps128_mask, "UcV4fV4fIiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dIiUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cmppd256_mask, "UcV4dV4dIiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cmppd128_mask, "UcV2dV2dIiUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_rndscaleps_mask, "V16fV16fIiV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rndscalepd_mask, "V8dV8dIiV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtps2dq512_mask, "V16iV16fV16iUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2dq512_mask, "V8iV8dV8iUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtps2udq512_mask, "V16iV16fV16iUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2udq512_mask, "V8iV8dV8iUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_minps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_minpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_maxps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_maxpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtdq2ps512_mask, "V16fV16iV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fIiV16sUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pabsd512_mask, "V16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pabsq512_mask, "V8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmaxsd512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmaxsq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmaxud512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmaxuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pminsd512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pminsq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pminud512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pminuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8LLiV16iV16i", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8LLiV16iV16i", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16ffC*V16fUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadaps512_mask, "V16fV16fC*V16fUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadupd512_mask, "V8ddC*V8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadapd512_mask, "V8dV8dC*V8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storedqudi512_mask, "vLLi*V8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storedqusi512_mask, "vi*V16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeupd512_mask, "vd*V8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeapd512_mask, "vV8d*V8dUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeups512_mask, "vf*V16fUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeaps512_mask, "vV16f*V16fUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermt2vard512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_mask, "V16fV16iV16fV16fUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_mask, "V8dV8LLiV8dV8dUc", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_vpdpbusd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusd512_mask, "V16iV16iV16iV16iUs", "", "avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusds128_mask, "V4iV4iV4iV4iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusds256_mask, "V8iV8iV8iV8iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusds512_mask, "V16iV16iV16iV16iUs", "", "avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssd512_mask, "V16iV16iV16iV16iUs", "", "avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssds128_mask, "V4iV4iV4iV4iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssds256_mask, "V8iV8iV8iV8iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssds512_mask, "V16iV16iV16iV16iUs", "", "avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusd128_maskz, "V4iV4iV4iV4iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusd256_maskz, "V8iV8iV8iV8iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusd512_maskz, "V16iV16iV16iV16iUs", "", "avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusds128_maskz, "V4iV4iV4iV4iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusds256_maskz, "V8iV8iV8iV8iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusds512_maskz, "V16iV16iV16iV16iUs", "", "avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssd128_maskz, "V4iV4iV4iV4iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssd256_maskz, "V8iV8iV8iV8iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssd512_maskz, "V16iV16iV16iV16iUs", "", "avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssds128_maskz, "V4iV4iV4iV4iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssds256_maskz, "V8iV8iV8iV8iUc", "", "avx512vl,avx512vnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssds512_maskz, "V16iV16iV16iV16iUs", "", "avx512vnni")
-
-TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8iiC*V8iUcIi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8ddC*V8iUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16ffC*V16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8ddC*V8LLiUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8ffC*V8LLiUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLiLLiC*V8iUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16iiC*V16iUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLiLLiC*V8LLiUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8iiC*V8LLiUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vd*UcV8iV8dIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vf*UsV16iV16fIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vd*UcV8LLiV8dIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vf*UcV8LLiV8fIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vLLi*UcV8iV8LLiIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vi*UsV16iV16iIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vLLi*UcV8LLiV8LLiIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vi*UcV8LLiV8iIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8iLLiC*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16iiC*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLiLLiC*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLiiC*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iLLi*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16ii*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiLLi*IiIi", "", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLii*IiIi", "", "avx512pf")
-
-TARGET_BUILTIN(__builtin_ia32_knothi, "UsUs", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_cmpb128_mask, "UsV16cV16cIiUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cmpd128_mask, "UcV4iV4iIiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cmpq128_mask, "UcV2LLiV2LLiIiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cmpw128_mask, "UcV8sV8sIiUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cmpb256_mask, "UiV32cV32cIiUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cmpd256_mask, "UcV8iV8iIiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cmpq256_mask, "UcV4LLiV4LLiIiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cmpw256_mask, "UsV16sV16sIiUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cmpb512_mask, "ULLiV64cV64cIiULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cmpd512_mask, "UsV16iV16iIiUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8LLiV8LLiIiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cmpw512_mask, "UiV32sV32sIiUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_ucmpb128_mask, "UsV16cV16cIiUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_ucmpd128_mask, "UcV4iV4iIiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ucmpq128_mask, "UcV2LLiV2LLiIiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ucmpw128_mask, "UcV8sV8sIiUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_ucmpb256_mask, "UiV32cV32cIiUi", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_ucmpd256_mask, "UcV8iV8iIiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ucmpq256_mask, "UcV4LLiV4LLiIiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_ucmpw256_mask, "UsV16sV16sIiUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_ucmpb512_mask, "ULLiV64cV64cIiULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8LLiV8LLiIiUc", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "", "avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_pabsb512_mask, "V64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pabsw512_mask, "V32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packssdw512, "V32sV16iV16i", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packsswb512, "V64cV32sV32s", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packusdw512, "V32sV16iV16i", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_packuswb512, "V64cV32sV32s", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddusw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxub512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaxuw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminub512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pminuw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pshufb512, "V64cV64cV64c", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_vpermi2varhi512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varhi512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varhi512_maskz, "V32sV32sV32sV32sUi", "", "avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_vpconflictdi_128_mask, "V2LLiV2LLiV2LLiUc","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpconflictdi_256_mask, "V4LLiV4LLiV4LLiUc","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpconflictsi_128_mask, "V4iV4iV4iUc","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpconflictsi_256_mask, "V8iV8iV8iUc","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpconflictdi_512_mask, "V8LLiV8LLiV8LLiUc", "", "avx512cd")
-TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512_mask, "V16iV16iV16iUs", "", "avx512cd")
-TARGET_BUILTIN(__builtin_ia32_vplzcntd_512_mask, "V16iV16iV16iUs", "", "avx512cd")
-TARGET_BUILTIN(__builtin_ia32_vplzcntq_512_mask, "V8LLiV8LLiV8LLiUc", "", "avx512cd")
-
-TARGET_BUILTIN(__builtin_ia32_vpopcntd_128, "V4iV4i", "", "avx512vpopcntdq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpopcntq_128, "V2LLiV2LLi", "", "avx512vpopcntdq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpopcntd_256, "V8iV8i", "", "avx512vpopcntdq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpopcntq_256, "V4LLiV4LLi", "", "avx512vpopcntdq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpopcntd_512, "V16iV16i", "", "avx512vpopcntdq")
-TARGET_BUILTIN(__builtin_ia32_vpopcntq_512, "V8LLiV8LLi", "", "avx512vpopcntdq")
-
-TARGET_BUILTIN(__builtin_ia32_vpopcntb_128, "V16cV16c", "", "avx512vl,avx512bitalg")
-TARGET_BUILTIN(__builtin_ia32_vpopcntw_128, "V8sV8s", "", "avx512vl,avx512bitalg")
-TARGET_BUILTIN(__builtin_ia32_vpopcntb_256, "V32cV32c", "", "avx512vl,avx512bitalg")
-TARGET_BUILTIN(__builtin_ia32_vpopcntw_256, "V16sV16s", "", "avx512vl,avx512bitalg")
-TARGET_BUILTIN(__builtin_ia32_vpopcntb_512, "V64cV64c", "", "avx512bitalg")
-TARGET_BUILTIN(__builtin_ia32_vpopcntw_512, "V32sV32s", "", "avx512bitalg")
-
-TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb128_mask, "UsV16cV16cUs", "", "avx512vl,avx512bitalg")
-TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb256_mask, "UiV32cV32cUi", "", "avx512vl,avx512bitalg")
-TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb512_mask, "ULLiV64cV64cULLi", "", "avx512bitalg")
-
-TARGET_BUILTIN(__builtin_ia32_vpermi2varhi128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varhi256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varhi128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varhi128_maskz, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varhi256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varhi256_maskz, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_pmulhrsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhuw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_addpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_addps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_divpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_divps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_mulpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_mulps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_subpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_subps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_pmaddubsw512_mask, "V32sV64cV64cV32sUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaddwd512_mask, "V16iV32sV32sV16iUs", "", "avx512bw")
-
-TARGET_BUILTIN(__builtin_ia32_addss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_divss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_mulss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_subss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_maxss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_minss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_addsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_divsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_mulsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_subsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_maxsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_minsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_compressdf128_mask, "V2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compressdf256_mask, "V4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compressdi128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compressdi256_mask, "V4LLiV4LLiV4LLiUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_compresshi128_mask, "V8sV8sV8sUc","","avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compresshi256_mask, "V16sV16sV16sUs","","avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compressqi128_mask, "V16cV16cV16cUs","","avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compressqi256_mask, "V32cV32cV32cUi","","avx512vl,avx512vbmi2")
-
-TARGET_BUILTIN(__builtin_ia32_compresssf128_mask, "V4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compresssf256_mask, "V8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compresssi128_mask, "V4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compresssi256_mask, "V8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compressstoredf128_mask, "vV2d*V2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compressstoredf256_mask, "vV4d*V4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compressstoredi128_mask, "vV2LLi*V2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compressstoredi256_mask, "vV4LLi*V4LLiUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_compressstorehi128_mask, "vV8s*V8sUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compressstorehi256_mask, "vV16s*V16sUs", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compressstoreqi128_mask, "vV16c*V16cUs", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compressstoreqi256_mask, "vV32c*V32cUi", "", "avx512vl,avx512vbmi2")
-
-TARGET_BUILTIN(__builtin_ia32_compressstoresf128_mask, "vV4f*V4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compressstoresf256_mask, "vV8f*V8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compressstoresi128_mask, "vV4i*V4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_compressstoresi256_mask, "vV8i*V8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtdq2ps128_mask, "V4fV4iV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtdq2ps256_mask, "V8fV8iV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2dq128_mask, "V4iV2dV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2dq256_mask, "V4iV4dV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2ps_mask, "V4fV2dV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2ps256_mask, "V4fV4dV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2udq128_mask, "V4iV2dV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2udq256_mask, "V4iV4dV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtps2dq128_mask, "V4iV4fV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtps2dq256_mask, "V8iV8fV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtps2pd128_mask, "V2dV4fV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtps2pd256_mask, "V4dV4fV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtps2udq128_mask, "V4iV4fV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtps2udq256_mask, "V8iV8fV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2dq128_mask, "V4iV2dV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2dq256_mask, "V4iV4dV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2udq128_mask, "V4iV2dV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2udq256_mask, "V4iV4dV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvttps2dq128_mask, "V4iV4fV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvttps2dq256_mask, "V8iV8fV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvttps2udq128_mask, "V4iV4fV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvttps2udq256_mask, "V8iV8fV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtudq2ps128_mask, "V4fV4iV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtudq2ps256_mask, "V8fV8iV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expanddf128_mask, "V2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expanddf256_mask, "V4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expanddi128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expanddi256_mask, "V4LLiV4LLiV4LLiUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_expandhi128_mask, "V8sV8sV8sUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandhi256_mask, "V16sV16sV16sUs", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandqi128_mask, "V16cV16cV16cUs", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandqi256_mask, "V32cV32cV32cUi", "", "avx512vl,avx512vbmi2")
-
-TARGET_BUILTIN(__builtin_ia32_expandloaddf128_mask, "V2dV2d*V2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expandloaddf256_mask, "V4dV4d*V4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expandloaddi128_mask, "V4iV2LLi*V2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expandloaddi256_mask, "V4LLiV4LLi*V4LLiUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_expandloadhi128_mask, "V8sV8sC*V8sUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandloadhi256_mask, "V16sV16sC*V16sUs", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandloadqi128_mask, "V16cV16cC*V16cUs", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandloadqi256_mask, "V32cV32cC*V32cUi", "", "avx512vl,avx512vbmi2")
-
-TARGET_BUILTIN(__builtin_ia32_expandloadsf128_mask, "V4fV4f*V4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expandloadsf256_mask, "V8fV8f*V8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expandloadsi128_mask, "V4iV4i*V4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expandloadsi256_mask, "V8iV8i*V8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expandsf128_mask, "V4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expandsf256_mask, "V8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expandsi128_mask, "V4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_expandsi256_mask, "V8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_getexppd128_mask, "V2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_getexppd256_mask, "V4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_getexpps128_mask, "V4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_getexpps256_mask, "V8fV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pabsq128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pabsq256_mask, "V4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxsq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxsq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxuq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmaxuq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminsq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminsq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminuq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pminuq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_rndscalepd_128_mask, "V2dV2dIiV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_rndscalepd_256_mask, "V4dV4dIiV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_rndscaleps_128_mask, "V4fV4fIiV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_rndscaleps_256_mask, "V8fV8fIiV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scalefpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scalefpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scalefps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scalefps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vd*UcV2LLiV2dIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vLLi*UcV2LLiV2LLiIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vd*UcV4LLiV4dIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vLLi*UcV4LLiV4LLiIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vf*UcV2LLiV4fIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vi*UcV2LLiV4iIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vf*UcV4LLiV4fIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vi*UcV4LLiV4iIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vd*UcV4iV2dIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vLLi*UcV4iV2LLiIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vd*UcV4iV4dIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vLLi*UcV4iV4LLiIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vf*UcV4iV4fIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vi*UcV4iV4iIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vf*UcV8iV8fIi", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vi*UcV8iV8iIi", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vpermi2vard128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2vard256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varpd128_mask, "V2dV2dV2LLiV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varpd256_mask, "V4dV4dV4LLiV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varps128_mask, "V4fV4fV4iV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varps256_mask, "V8fV8fV8iV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2vard128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2vard128_maskz, "V4iV4iV4iV4iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2vard256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2vard256_maskz, "V8iV8iV8iV8iUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varpd128_mask, "V2dV2LLiV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varpd128_maskz, "V2dV2LLiV2dV2dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varpd256_mask, "V4dV4LLiV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varpd256_maskz, "V4dV4LLiV4dV4dUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varps128_mask, "V4fV4iV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varps128_maskz, "V4fV4iV4fV4fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varps256_mask, "V8fV8iV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varps256_maskz, "V8fV8iV8fV8fUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
-
-TARGET_BUILTIN(__builtin_ia32_vpshldd128_mask, "V4iV4iV4iIiV4iUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldd256_mask, "V8iV8iV8iIiV8iUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldd512_mask, "V16iV16iV16iIiV16iUs", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldq128_mask, "V2LLiV2LLiV2LLiIiV2LLiUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldq256_mask, "V4LLiV4LLiV4LLiIiV4LLiUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldq512_mask, "V8LLiV8LLiV8LLiIiV8LLiUc", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldw128_mask, "V8sV8sV8sIiV8sUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldw256_mask, "V16sV16sV16sIiV16sUs", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldw512_mask, "V32sV32sV32sIiV32sUi", "", "avx512vbmi2")
-
-TARGET_BUILTIN(__builtin_ia32_vpshldvd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd512_mask, "V16iV16iV16iV16iUs", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw512_mask, "V32sV32sV32sV32sUi", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd128_maskz, "V4iV4iV4iV4iUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd256_maskz, "V8iV8iV8iV8iUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd512_maskz, "V16iV16iV16iV16iUs", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw128_maskz, "V8sV8sV8sV8sUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw256_maskz, "V16sV16sV16sV16sUs", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw512_maskz, "V32sV32sV32sV32sUi", "", "avx512vbmi2")
-
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_mask, "V16iV16iV16iV16iUs", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_mask, "V32sV32sV32sV32sUi", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_maskz, "V4iV4iV4iV4iUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_maskz, "V8iV8iV8iV8iUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_maskz, "V16iV16iV16iV16iUs", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_maskz, "V8sV8sV8sV8sUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_maskz, "V16sV16sV16sV16sUs", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_maskz, "V32sV32sV32sV32sUi", "", "avx512vbmi2")
-
-TARGET_BUILTIN(__builtin_ia32_vpshrdd128_mask, "V4iV4iV4iiV4iUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdd256_mask, "V8iV8iV8iiV8iUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdd512_mask, "V16iV16iV16iiV16iUs", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdq128_mask, "V2LLiV2LLiV2LLiiV2LLiUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdq256_mask, "V4LLiV4LLiV4LLiiV4LLiUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdq512_mask, "V8LLiV8LLiV8LLiiV8LLiUc", "", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdw128_mask, "V8sV8sV8siV8sUc", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdw256_mask, "V16sV16sV16siV16sUs", "", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdw512_mask, "V32sV32sV32siV32sUi", "", "avx512vbmi2")
-
-TARGET_BUILTIN(__builtin_ia32_pmovswb512_mask, "V32cV32sV32cUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovuswb512_mask, "V32cV32sV32cUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovwb512_mask, "V32cV32sV32cUi", "", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2qq128_mask, "V2LLiV2dV2LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2qq256_mask, "V4LLiV4dV4LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq128_mask, "V2LLiV2dV2LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq256_mask, "V4LLiV4dV4LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtps2qq128_mask, "V2LLiV4fV2LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtps2qq256_mask, "V4LLiV4fV4LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtps2uqq128_mask, "V2LLiV4fV2LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtps2uqq256_mask, "V4LLiV4fV4LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtqq2pd128_mask, "V2dV2LLiV2dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtqq2pd256_mask, "V4dV4LLiV4dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtqq2ps128_mask, "V4fV2LLiV4fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtqq2ps256_mask, "V4fV4LLiV4fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2qq128_mask, "V2LLiV2dV2LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2qq256_mask, "V4LLiV4dV4LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq128_mask, "V2LLiV2dV2LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq256_mask, "V4LLiV4dV4LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttps2qq128_mask, "V2LLiV4fV2LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttps2qq256_mask, "V4LLiV4fV4LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttps2uqq128_mask, "V2LLiV4fV2LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttps2uqq256_mask, "V4LLiV4fV4LLiUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd128_mask, "V2dV2LLiV2dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd256_mask, "V4dV4LLiV4dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps128_mask, "V4fV2LLiV4fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps256_mask, "V4fV4LLiV4fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_rangepd128_mask, "V2dV2dV2dIiV2dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_rangepd256_mask, "V4dV4dV4dIiV4dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_rangeps128_mask, "V4fV4fV4fIiV4fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_rangeps256_mask, "V8fV8fV8fIiV8fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_rangesd128_round_mask, "V2dV2dV2dV2dUcIiIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_rangess128_round_mask, "V4fV4fV4fV4fUcIiIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_reducepd128_mask, "V2dV2dIiV2dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_reducepd256_mask, "V4dV4dIiV4dUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_reduceps128_mask, "V4fV4fIiV4fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_reduceps256_mask, "V8fV8fIiV8fUc", "", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_reducesd_mask, "V2dV2dV2dV2dUcIiIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_reducess_mask, "V4fV4fV4fV4fUcIiIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_pmovswb128_mask, "V16cV8sV16cUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovswb256_mask, "V16cV16sV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovuswb128_mask, "V16cV8sV16cUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovuswb256_mask, "V16cV16sV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovwb128_mask, "V16cV8sV16cUc", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovwb256_mask, "V16cV16sV16cUs", "", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtps2qq512_mask, "V8LLiV8fV8LLiUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtps2uqq512_mask, "V8LLiV8fV8LLiUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtqq2pd512_mask, "V8dV8LLiV8dUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtqq2ps512_mask, "V8fV8LLiV8fUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttps2qq512_mask, "V8LLiV8fV8LLiUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttps2uqq512_mask, "V8LLiV8fV8LLiUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd512_mask, "V8dV8LLiV8dUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps512_mask, "V8fV8LLiV8fUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_rangepd512_mask, "V8dV8dV8dIiV8dUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_rangeps512_mask, "V16fV16fV16fIiV16fUsIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_reducepd512_mask, "V8dV8dIiV8dUcIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_reduceps512_mask, "V16fV16fIiV16fUsIi", "", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_prold512_mask, "V16iV16iIiV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_prolq512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_prold128_mask, "V4iV4iIiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prold256_mask, "V8iV8iIiV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prolq128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prolq256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prolvd512_mask, "V16iV16iV16iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_prolvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_prord512_mask, "V16iV16iiV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_prorq512_mask, "V8LLiV8LLiiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_prolvd128_mask, "V4iV4iV4iV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prolvd256_mask, "V8iV8iV8iV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prolvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prolvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prord128_mask, "V4iV4iIiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prord256_mask, "V8iV8iIiV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prorq128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prorq256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prorvd512_mask, "V16iV16iV16iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_prorvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_prorvd128_mask, "V4iV4iV4iV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prorvd256_mask, "V8iV8iV8iV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prorvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prorvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllv32hi, "V32sV32sV32s","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psllw512, "V32sV32sV8s","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psllwi512, "V32sV32si","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psllv16hi, "V16sV16sV16s","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psllv8hi, "V8sV8sV8s","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pslldi512, "V16iV16ii","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psllqi512, "V8LLiV8LLii","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlv32hi, "V32sV32sV32s","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrlv16hi, "V16sV16sV16s","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrlv8hi, "V8sV8sV8s","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrldi512, "V16iV16ii","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlqi512, "V8LLiV8LLii","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrav32hi, "V32sV32sV32s","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrav16hi, "V16sV16sV16s","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrav8hi, "V8sV8sV8s","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psravq128, "V2LLiV2LLiV2LLi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psravq256, "V4LLiV4LLiV4LLi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psraw512, "V32sV32sV8s","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrawi512, "V32sV32si","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrlw512, "V32sV32sV8s","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrlwi512, "V32sV32si","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_movdqa32load128_mask, "V4iV4i*V4iUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_movdqa32load256_mask, "V8iV8i*V8iUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_movdqa32load512_mask, "V16iV16iC*V16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_movdqa32store512_mask, "vV16i*V16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_movdqa64load512_mask, "V8LLiV8LLiC*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_movdqa64store512_mask, "vV8LLi*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_movdqa32store128_mask, "vV4i*V4iUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_movdqa32store256_mask, "vV8i*V8iUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_movdqa64load128_mask, "V2LLiV2LLiC*V2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_movdqa64load256_mask, "V4LLiV4LLiC*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_movdqa64store128_mask, "vV2LLi*V2LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_movdqa64store256_mask, "vV4LLi*V4LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52huq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512ifma,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52huq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc","","avx512ifma,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52huq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512ifma,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52huq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc","","avx512ifma,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52luq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512ifma,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52luq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc","","avx512ifma,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52luq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512ifma,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52luq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc","","avx512ifma,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varqi512_mask, "V64cV64cV64cV64cULLi","","avx512vbmi")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varqi512_mask, "V64cV64cV64cV64cULLi","","avx512vbmi")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varqi512_maskz, "V64cV64cV64cV64cULLi","","avx512vbmi")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varqi128_mask, "V16cV16cV16cV16cUs","","avx512vbmi,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varqi256_mask, "V32cV32cV32cV32cUi","","avx512vbmi,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varqi128_mask, "V16cV16cV16cV16cUs","","avx512vbmi,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varqi128_maskz, "V16cV16cV16cV16cUs","","avx512vbmi,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varqi256_mask, "V32cV32cV32cV32cUi","","avx512vbmi,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varqi256_maskz, "V32cV32cV32cV32cUi","","avx512vbmi,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vcomisd, "iV2dV2dIiIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcomiss, "iV4fV4fIiIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_kunpckdi, "ULLiULLiULLi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_kunpcksi, "UiUiUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_loaddquhi512_mask, "V32sV32s*V32sUi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_loaddquqi512_mask, "V64cV64c*V64cULLi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_mask, "V8dV8dV8dV8LLiIiUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_maskz, "V8dV8dV8dV8LLiIiUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_fixupimmps512_mask, "V16fV16fV16fV16iIiUsIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_fixupimmps512_maskz, "V16fV16fV16fV16iIiUsIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_fixupimmsd_mask, "V2dV2dV2dV2LLiIiUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_fixupimmsd_maskz, "V2dV2dV2dV2LLiIiUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_fixupimmss_mask, "V4fV4fV4fV4iIiUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_fixupimmss_maskz, "V4fV4fV4fV4iIiUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_getexpsd128_round_mask, "V2dV2dV2dV2dUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_getexpss128_round_mask, "V4fV4fV4fV4fUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_getmantsd_round_mask, "V2dV2dV2dIiV2dUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_getmantss_round_mask, "V4fV4fV4fIiV4fUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_loaddquhi128_mask, "V8sV8s*V8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loaddquhi256_mask, "V16sV16s*V16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loaddquqi128_mask, "V16cV16c*V16cUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loaddquqi256_mask, "V32cV32c*V32cUi","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_mask, "V2dV2dV2dV2LLiIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_maskz, "V2dV2dV2dV2LLiIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_mask, "V4dV4dV4dV4LLiIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_maskz, "V4dV4dV4dV4LLiIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fixupimmps128_mask, "V4fV4fV4fV4iIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fixupimmps128_maskz, "V4fV4fV4fV4iIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fixupimmps256_mask, "V8fV8fV8fV8iIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fixupimmps256_maskz, "V8fV8fV8fV8iIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loadapd128_mask, "V2dV2d*V2dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loadsd128_mask, "V8dV8d*V8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadapd256_mask, "V4dV4d*V4dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loadaps128_mask, "V4fV4f*V4fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loadss128_mask, "V16fV16f*V16fUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadaps256_mask, "V8fV8f*V8fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loaddqudi128_mask, "V2LLiV2LLi*V2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loaddqudi256_mask, "V4LLiV4LLi*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loaddqusi128_mask, "V4iV4i*V4iUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_loaddqusi256_mask, "V8iV8i*V8iUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadupd128_mask, "V2dV2d*V2dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loadupd256_mask, "V4dV4d*V4dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loadups128_mask, "V4fV4f*V4fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_loadups256_mask, "V8fV8f*V8fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storedquhi512_mask, "vV32s*V32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_storedquqi512_mask, "vV64c*V64cULLi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_storedquhi128_mask, "vV8s*V8sUc","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_storedquhi256_mask, "vV16s*V16sUs","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_storedquqi128_mask, "vV16c*V16cUs","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_storedquqi256_mask, "vV32c*V32cUi","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_storeapd128_mask, "vV2d*V2dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storesd128_mask, "vV8d*V8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeapd256_mask, "vV4d*V4dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storeaps128_mask, "vV4f*V4fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storess128_mask, "vV16f*V16fUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeaps256_mask, "vV8f*V8fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storedqudi128_mask, "vV2LLi*V2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storedqudi256_mask, "vV4LLi*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storedqusi128_mask, "vV4i*V4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storedqusi256_mask, "vV8i*V8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storeupd128_mask, "vV2d*V2dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storeupd256_mask, "vV4d*V4dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storeups128_mask, "vV4f*V4fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storeups256_mask, "vV8f*V8fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_rcp14pd128_mask, "V2dV2dV2dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_rcp14pd256_mask, "V4dV4dV4dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_rcp14ps128_mask, "V4fV4fV4fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_rcp14ps256_mask, "V8fV8fV8fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vplzcntd_128_mask, "V4iV4iV4iUc","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vplzcntd_256_mask, "V8iV8iV8iUc","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vplzcntq_128_mask, "V2LLiV2LLiV2LLiUc","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vplzcntq_256_mask, "V4LLiV4LLiV4LLiUc","","avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vcvtsd2si32, "iV2dIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi32, "UiV2dIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtss2si32, "iV4fIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtss2usi32, "UiV4fIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvttsd2si32, "iV2dIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi32, "UiV2dIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvttss2si32, "iV4fIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvttss2usi32, "UiV4fIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermi2vard512_mask, "V16iV16iV16iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varpd512_mask, "V8dV8dV8LLiV8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varps512_mask, "V16fV16fV16iV16fUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512, "V8dV8dV8LLi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarps512, "V16fV16fV16i","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermt2vard512_maskz, "V16iV16iV16iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_maskz, "V8dV8LLiV8dV8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_maskz, "V16fV16iV16fV16fUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_rndscalesd_round_mask, "V2dV2dV2dV2dUcIiIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_rndscaless_round_mask, "V4fV4fV4fV4fUcIiIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_scalefpd512_mask, "V8dV8dV8dV8dUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_scalefps512_mask, "V16fV16fV16fV16fUsIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_scalefsd_round_mask, "V2dV2dV2dV2dUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_scalefss_round_mask, "V4fV4fV4fV4fUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psradi512, "V16iV16ii","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psraqi512, "V8LLiV8LLii","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psraq128, "V2LLiV2LLiV2LLi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psraq256, "V4LLiV4LLiV2LLi","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psraqi128, "V2LLiV2LLii","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psraqi256, "V4LLiV4LLii","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pslld512, "V16iV16iV4i","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psllq512, "V8LLiV8LLiV2LLi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psllv16si, "V16iV16iV16i","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psllv8di, "V8LLiV8LLiV8LLi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrad512, "V16iV16iV4i","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psraq512, "V8LLiV8LLiV2LLi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrav16si, "V16iV16iV16i","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrav8di, "V8LLiV8LLiV8LLi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrld512, "V16iV16iV4i","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlq512, "V8LLiV8LLiV2LLi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlv16si, "V16iV16iV16i","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlv8di, "V8LLiV8LLiV8LLi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pternlogd512_mask, "V16iV16iV16iV16iIiUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pternlogd512_maskz, "V16iV16iV16iV16iIiUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pternlogq512_mask, "V8LLiV8LLiV8LLiV8LLiIiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pternlogq512_maskz, "V8LLiV8LLiV8LLiV8LLiIiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pternlogd128_mask, "V4iV4iV4iV4iIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pternlogd128_maskz, "V4iV4iV4iV4iIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pternlogd256_mask, "V8iV8iV8iV8iIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pternlogd256_maskz, "V8iV8iV8iV8iIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pternlogq128_mask, "V2LLiV2LLiV2LLiV2LLiIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pternlogq128_maskz, "V2LLiV2LLiV2LLiV2LLiIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pternlogq256_mask, "V4LLiV4LLiV4LLiV4LLiIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pternlogq256_maskz, "V4LLiV4LLiV4LLiV4LLiIiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_shuf_f32x4_mask, "V16fV16fV16fIiV16fUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_shuf_f64x2_mask, "V8dV8dV8dIiV8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_shuf_i32x4_mask, "V16iV16iV16iIiV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_shuf_i64x2_mask, "V8LLiV8LLiV8LLiIiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_shuf_f32x4_256_mask, "V8fV8fV8fIiV8fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_shuf_f64x2_256_mask, "V4dV4dV4dIiV4dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_shuf_i32x4_256_mask, "V8iV8iV8iIiV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_shuf_i64x2_256_mask, "V4LLiV4LLiV4LLiIiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_sqrtsd_round_mask, "V2dV2dV2dV2dUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_sqrtss_round_mask, "V4fV4fV4fV4fUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14pd128_mask, "V2dV2dV2dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14pd256_mask, "V4dV4dV4dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14ps128_mask, "V4fV4fV4fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14ps256_mask, "V8fV8fV8fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtb2mask512, "ULLiV64c","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2b512, "V64cULLi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2w512, "V32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cvtd2mask512, "UsV16i","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2d512, "V16iUs","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2q512, "V8LLiUc","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtq2mask512, "UcV8LLi","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtb2mask128, "UsV16c","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtb2mask256, "UiV32c","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2b128, "V16cUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2b256, "V32cUi","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2w128, "V8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2w256, "V16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtd2mask128, "UcV4i","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtd2mask256, "UcV8i","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2d128, "V4iUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2d256, "V8iUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2q128, "V2LLiUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2q256, "V4LLiUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2LLi","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4LLi","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsdb512_mask, "V16cV16iV16cUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsdb512mem_mask, "vV16c*V16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovswb512mem_mask, "vV32c*V32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovsdw512_mask, "V16sV16iV16sUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsdw512mem_mask, "vV16s*V16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsqb512_mask, "V16cV8LLiV16cUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsqb512mem_mask, "vV16c*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsqd512_mask, "V8iV8LLiV8iUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsqd512mem_mask, "vV8i*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsqw512_mask, "V8sV8LLiV8sUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsqw512mem_mask, "vV8s*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsdb128_mask, "V16cV4iV16cUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsdb128mem_mask, "vV16c*V4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovswb128mem_mask, "vV16c*V8sUc","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovsdb256_mask, "V16cV8iV16cUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsdb256mem_mask, "vV16c*V8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovswb256mem_mask, "vV16c*V16sUs","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovsdw128_mask, "V8sV4iV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsdw128mem_mask, "vV8s*V4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsdw256_mask, "V8sV8iV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsdw256mem_mask, "vV8s*V8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsqb128_mask, "V16cV2LLiV16cUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsqb128mem_mask, "vV16c*V2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsqb256_mask, "V16cV4LLiV16cUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsqb256mem_mask, "vV16c*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsqd128_mask, "V4iV2LLiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsqd128mem_mask, "vV4i*V2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsqd256_mask, "V4iV4LLiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsqd256mem_mask, "vV4i*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsqw128_mask, "V8sV2LLiV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsqw128mem_mask, "vV8s*V2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsqw256_mask, "V8sV4LLiV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsqw256mem_mask, "vV8s*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusdb512_mask, "V16cV16iV16cUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusdb512mem_mask, "vV16c*V16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovuswb512mem_mask, "vV32c*V32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovusdw512_mask, "V16sV16iV16sUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusdw512mem_mask, "vV16s*V16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusqb512_mask, "V16cV8LLiV16cUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusqb512mem_mask, "vV16c*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusqd512_mask, "V8iV8LLiV8iUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusqd512mem_mask, "vV8i*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusqw512_mask, "V8sV8LLiV8sUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusqw512mem_mask, "vV8s*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusdb128_mask, "V16cV4iV16cUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusdb128mem_mask, "vV16c*V4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovuswb128mem_mask, "vV16c*V8sUc","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovusdb256_mask, "V16cV8iV16cUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusdb256mem_mask, "vV16c*V8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovuswb256mem_mask, "vV16c*V16sUs","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovusdw128_mask, "V8sV4iV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusdw128mem_mask, "vV8s*V4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusdw256_mask, "V8sV8iV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusdw256mem_mask, "vV8s*V8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusqb128_mask, "V16cV2LLiV16cUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusqb128mem_mask, "vV16c*V2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusqb256_mask, "V16cV4LLiV16cUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusqb256mem_mask, "vV16c*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusqd128_mask, "V4iV2LLiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusqd128mem_mask, "vV4i*V2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusqd256_mask, "V4iV4LLiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusqd256mem_mask, "vV4i*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusqw128_mask, "V8sV2LLiV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusqw128mem_mask, "vV8s*V2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusqw256_mask, "V8sV4LLiV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusqw256mem_mask, "vV8s*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovdb512_mask, "V16cV16iV16cUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovdb512mem_mask, "vV16c*V16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovwb512mem_mask, "vV32c*V32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovdw512_mask, "V16sV16iV16sUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovdw512mem_mask, "vV16s*V16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovqb512_mask, "V16cV8LLiV16cUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovqb512mem_mask, "vV16c*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovqd512_mask, "V8iV8LLiV8iUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovqd512mem_mask, "vV8i*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovqw512_mask, "V8sV8LLiV8sUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovqw512mem_mask, "vV8s*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovdb128_mask, "V16cV4iV16cUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovwb128mem_mask, "vV16c*V8sUc","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovdb128mem_mask, "vV16c*V4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovdb256_mask, "V16cV8iV16cUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovdb256mem_mask, "vV16c*V8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovwb256mem_mask, "vV16c*V16sUs","","avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovdw128_mask, "V8sV4iV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovdw128mem_mask, "vV8s*V4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovdw256_mask, "V8sV8iV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovdw256mem_mask, "vV8s*V8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovqb128_mask, "V16cV2LLiV16cUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovqb128mem_mask, "vV16c*V2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovqb256_mask, "V16cV4LLiV16cUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovqb256mem_mask, "vV16c*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovqd128_mask, "V4iV2LLiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovqd128mem_mask, "vV4i*V2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovqd256_mask, "V4iV4LLiV4iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovqd256mem_mask, "vV4i*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovqw128_mask, "V8sV2LLiV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovqw128mem_mask, "vV8s*V2LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovqw256_mask, "V8sV4LLiV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovqw256mem_mask, "vV8s*V4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_getmantpd128_mask, "V2dV2diV2dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_getmantpd256_mask, "V4dV4diV4dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_getmantps128_mask, "V4fV4fiV4fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_getmantps256_mask, "V8fV8fiV8fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_getmantpd512_mask, "V8dV8diV8dUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_getmantps512_mask, "V16fV16fiV16fUsIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_getexppd512_mask, "V8dV8dV8dUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_getexpps512_mask, "V16fV16fV16fUsIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddss3_mask, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddss3_maskz, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddss3_mask3, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_maskz, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask3, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmsubsd3_mask3, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmsubss3_mask3, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubsd3_mask3, "V2dV2dV2dV2dUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfnmsubss3_mask3, "V4fV4fV4fV4fUcIi", "", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_permvarhi512_mask, "V32sV32sV32sV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_permvardf512_mask, "V8dV8dV8LLiV8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_permvardi512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_permvarsf512_mask, "V16fV16fV16iV16fUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_permvarsi512_mask, "V16iV16iV16iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_permvarqi512_mask, "V64cV64cV64cV64cULLi","","avx512vbmi")
-TARGET_BUILTIN(__builtin_ia32_permvarqi128_mask, "V16cV16cV16cV16cUs","","avx512vbmi,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_permvarqi256_mask, "V32cV32cV32cV32cUi","","avx512vbmi,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_permvarhi128_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_permvarhi256_mask, "V16sV16sV16sV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_permvardf256_mask, "V4dV4dV4LLiV4dUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_permvardi256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_permvarsf256_mask, "V8fV8fV8iV8fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_permvarsi256_mask, "V8iV8iV8iV8iUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fpclasspd128_mask, "UcV2dIiUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fpclasspd256_mask, "UcV4dIiUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fpclassps128_mask, "UcV4fIiUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fpclassps256_mask, "UcV8fIiUc","","avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fpclassps512_mask, "UsV16fIiUs","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_fpclasspd512_mask, "UcV8dIiUc","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_fpclasssd_mask, "UcV2dIiUc","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_fpclassss_mask, "UcV4fIiUc","","avx512dq")
-TARGET_BUILTIN(__builtin_ia32_kandhi, "UsUsUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_kandnhi, "UsUsUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_korhi, "UsUsUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_kortestchi, "iUsUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_kortestzhi, "iUsUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_kunpckhi, "UsUsUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_kxnorhi, "UsUsUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_kxorhi, "UsUsUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_palignr512_mask, "V64cV64cV64cIiV64cULLi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_dbpsadbw128_mask, "V8sV16cV16cIiV8sUc","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_dbpsadbw256_mask, "V16sV32cV32cIiV16sUs","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_dbpsadbw512_mask, "V32sV64cV64cIiV32sUi","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psadbw512, "V8LLiV64cV64c","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_compressdf512_mask, "V8dV8dV8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_compressdi512_mask, "V8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_compresshi512_mask, "V32sV32sV32sUi","","avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compressqi512_mask, "V64cV64cV64cULLi","","avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compresssf512_mask, "V16fV16fV16fUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_compresssi512_mask, "V16iV16iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cmpsd_mask, "UcV2dV2dIiUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cmpss_mask, "UcV4fV4fIiUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_expanddf512_mask, "V8dV8dV8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_expanddi512_mask, "V8LLiV8LLiV8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_expandhi512_mask, "V32sV32sV32sUi","","avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandqi512_mask, "V64cV64cV64cULLi","","avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandloaddf512_mask, "V8dV8dC*V8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_expandloaddi512_mask, "V8LLiV8LLiC*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_expandloadhi512_mask, "V32sV32sC*V32sUi","","avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandloadqi512_mask, "V64cV64cC*V64cULLi","","avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandloadsf512_mask, "V16fV16fC*V16fUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_expandloadsi512_mask, "V16iV16iC*V16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_expandsf512_mask, "V16fV16fV16fUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_expandsi512_mask, "V16iV16iV16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtps2pd512_mask, "V8dV8fV8dUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_compressstoredf512_mask, "vV8d*V8dUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_compressstoredi512_mask, "vV8LLi*V8LLiUc","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_compressstorehi512_mask, "vV32s*V32sUi","","avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compressstoreqi512_mask, "vV64c*V64cULLi","","avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compressstoresf512_mask, "vV16f*V16fUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_compressstoresi512_mask, "vV16i*V16iUs","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtph2ps_mask, "V4fV8sV4fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vcvtph2ps256_mask, "V8fV8sV8fUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vcvtps2ph_mask, "V8sV4fIiV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vcvtps2ph256_mask, "V8sV8fIiV8sUc","","avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtw2mask512, "UiV32s","","avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cvtw2mask128, "UcV8s","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtw2mask256, "UsV16s","","avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtsd2ss_round_mask, "V4fV4fV2dV4fUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtsi2ss32, "V4fV4fiIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtss2sd_round_mask, "V2dV2dV4fV2dUcIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtusi2sd32, "V2dV2dUi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtusi2ss32, "V4fV4fUiIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512_mask, "V64cV64cV64cV64cULLi","","avx512vbmi")
-TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128_mask, "V16cV16cV16cV16cUs","","avx512vbmi,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256_mask, "V32cV32cV32cV32cUi","","avx512vbmi,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_sqrtpd512, "V8dV8dIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_sqrtps512, "V16fV16fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rsqrt14sd_mask, "V2dV2dV2dV2dUc", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rsqrt14ss_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rsqrt14pd512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rsqrt14ps512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f")
+
+TARGET_BUILTIN(__builtin_ia32_rsqrt28sd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512er")
+TARGET_BUILTIN(__builtin_ia32_rsqrt28ss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512er")
+TARGET_BUILTIN(__builtin_ia32_rsqrt28pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er")
+TARGET_BUILTIN(__builtin_ia32_rsqrt28ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er")
+
+TARGET_BUILTIN(__builtin_ia32_rcp14sd_mask, "V2dV2dV2dV2dUc", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rcp14ss_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rcp14pd512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rcp14ps512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f")
+
+TARGET_BUILTIN(__builtin_ia32_rcp28sd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512er")
+TARGET_BUILTIN(__builtin_ia32_rcp28ss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512er")
+TARGET_BUILTIN(__builtin_ia32_rcp28pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er")
+TARGET_BUILTIN(__builtin_ia32_rcp28ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er")
+TARGET_BUILTIN(__builtin_ia32_exp2pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er")
+TARGET_BUILTIN(__builtin_ia32_exp2ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er")
+
+TARGET_BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f")
+
+TARGET_BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cmpps256_mask, "UcV8fV8fIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cmpps128_mask, "UcV4fV4fIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dIiUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cmppd256_mask, "UcV4dV4dIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cmppd128_mask, "UcV2dV2dIiUc", "ncV:128:", "avx512vl")
+
+TARGET_BUILTIN(__builtin_ia32_rndscaleps_mask, "V16fV16fIiV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rndscalepd_mask, "V8dV8dIiV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtps2dq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2dq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtps2udq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2udq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_minps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_minpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_maxps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_maxpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtdq2ps512_mask, "V16fV16iV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fIiV16sUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pabsd512, "V16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pabsq512, "V8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmaxsd512, "V16iV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmaxsq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmaxud512, "V16iV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmaxuq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pminsd512, "V16iV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pminsq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pminud512, "V16iV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pminuq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8LLiV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8LLiV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16ffC*V16fUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_loadaps512_mask, "V16fV16fC*V16fUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_loadupd512_mask, "V8ddC*V8dUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_loadapd512_mask, "V8dV8dC*V8dUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_storedqudi512_mask, "vLLi*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_storedqusi512_mask, "vi*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_storeupd512_mask, "vd*V8dUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_storeapd512_mask, "vV8d*V8dUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_storeups512_mask, "vf*V16fUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_storeaps512_mask, "vV16f*V16fUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_alignq512, "V8LLiV8LLiV8LLiIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_alignd512, "V16iV16iV16iIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_alignd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_alignd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_alignq128, "V2LLiV2LLiV2LLiIi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_alignq256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_extractf64x4_mask, "V4dV8dIiV4dUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_extractf32x4_mask, "V4fV16fIiV4fUc", "ncV:512:", "avx512f")
+
+TARGET_BUILTIN(__builtin_ia32_vpdpbusd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpbusd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpbusd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpbusds128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpbusds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpbusds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpwssd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpwssd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpwssd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpwssds128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpwssds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpwssds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
+
+TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUcIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8iiC*V8iUcIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8ddC*V8iUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16ffC*V16fUsIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8ddC*V8LLiUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8ffC*V8LLiUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLiLLiC*V8iUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16iiC*V16iUsIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLiLLiC*V8LLiUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8iiC*V8LLiUcIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vd*UcV8iV8dIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vf*UsV16iV16fIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vd*UcV8LLiV8dIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vf*UcV8LLiV8fIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vLLi*UcV8iV8LLiIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vi*UsV16iV16iIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vLLi*UcV8LLiV8LLiIi", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vi*UcV8LLiV8iIi", "nV:512:", "avx512f")
+
+TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8iLLiC*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16iiC*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLiLLiC*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLiiC*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iLLi*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16ii*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiLLi*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLii*IiIi", "nV:512:", "avx512pf")
+
+TARGET_BUILTIN(__builtin_ia32_knothi, "UsUs", "nc", "avx512f")
+
+TARGET_BUILTIN(__builtin_ia32_cmpb128_mask, "UsV16cV16cIiUs", "ncV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cmpd128_mask, "UcV4iV4iIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cmpq128_mask, "UcV2LLiV2LLiIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cmpw128_mask, "UcV8sV8sIiUc", "ncV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cmpb256_mask, "UiV32cV32cIiUi", "ncV:256:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cmpd256_mask, "UcV8iV8iIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cmpq256_mask, "UcV4LLiV4LLiIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cmpw256_mask, "UsV16sV16sIiUs", "ncV:256:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cmpb512_mask, "ULLiV64cV64cIiULLi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cmpd512_mask, "UsV16iV16iIiUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8LLiV8LLiIiUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cmpw512_mask, "UiV32sV32sIiUi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_ucmpb128_mask, "UsV16cV16cIiUs", "ncV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_ucmpd128_mask, "UcV4iV4iIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_ucmpq128_mask, "UcV2LLiV2LLiIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_ucmpw128_mask, "UcV8sV8sIiUc", "ncV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_ucmpb256_mask, "UiV32cV32cIiUi", "ncV:256:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_ucmpd256_mask, "UcV8iV8iIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_ucmpq256_mask, "UcV4LLiV4LLiIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_ucmpw256_mask, "UsV16sV16sIiUs", "ncV:256:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_ucmpb512_mask, "ULLiV64cV64cIiULLi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8LLiV8LLiIiUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "ncV:512:", "avx512bw")
+
+TARGET_BUILTIN(__builtin_ia32_pabsb512, "V64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pabsw512, "V32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_packssdw512, "V32sV16iV16i", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_packsswb512, "V64cV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_packusdw512, "V32sV16iV16i", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_packuswb512, "V64cV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_paddsb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_paddsw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_paddusw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmaxsb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmaxsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmaxub512, "V64cV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmaxuw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pminsb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pminsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pminub512, "V64cV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pminuw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pshufb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psubsb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psubsw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psubusb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psubusw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512bw")
+
+TARGET_BUILTIN(__builtin_ia32_vpconflictdi_128_mask, "V2LLiV2LLiV2LLiUc", "ncV:128:", "avx512cd,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpconflictdi_256_mask, "V4LLiV4LLiV4LLiUc", "ncV:256:", "avx512cd,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpconflictsi_128_mask, "V4iV4iV4iUc", "ncV:128:", "avx512cd,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpconflictsi_256_mask, "V8iV8iV8iUc", "ncV:256:", "avx512cd,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpconflictdi_512_mask, "V8LLiV8LLiV8LLiUc", "ncV:512:", "avx512cd")
+TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512cd")
+TARGET_BUILTIN(__builtin_ia32_vplzcntd_512, "V16iV16i", "ncV:512:", "avx512cd")
+TARGET_BUILTIN(__builtin_ia32_vplzcntq_512, "V8LLiV8LLi", "ncV:512:", "avx512cd")
+
+TARGET_BUILTIN(__builtin_ia32_vpopcntd_128, "V4iV4i", "ncV:128:", "avx512vpopcntdq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpopcntq_128, "V2LLiV2LLi", "ncV:128:", "avx512vpopcntdq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpopcntd_256, "V8iV8i", "ncV:256:", "avx512vpopcntdq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpopcntq_256, "V4LLiV4LLi", "ncV:256:", "avx512vpopcntdq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpopcntd_512, "V16iV16i", "ncV:512:", "avx512vpopcntdq")
+TARGET_BUILTIN(__builtin_ia32_vpopcntq_512, "V8LLiV8LLi", "ncV:512:", "avx512vpopcntdq")
+
+TARGET_BUILTIN(__builtin_ia32_vpopcntb_128, "V16cV16c", "ncV:128:", "avx512vl,avx512bitalg")
+TARGET_BUILTIN(__builtin_ia32_vpopcntw_128, "V8sV8s", "ncV:128:", "avx512vl,avx512bitalg")
+TARGET_BUILTIN(__builtin_ia32_vpopcntb_256, "V32cV32c", "ncV:256:", "avx512vl,avx512bitalg")
+TARGET_BUILTIN(__builtin_ia32_vpopcntw_256, "V16sV16s", "ncV:256:", "avx512vl,avx512bitalg")
+TARGET_BUILTIN(__builtin_ia32_vpopcntb_512, "V64cV64c", "ncV:512:", "avx512bitalg")
+TARGET_BUILTIN(__builtin_ia32_vpopcntw_512, "V32sV32s", "ncV:512:", "avx512bitalg")
+
+TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb128_mask, "UsV16cV16cUs", "ncV:128:", "avx512vl,avx512bitalg")
+TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb256_mask, "UiV32cV32cUi", "ncV:256:", "avx512vl,avx512bitalg")
+TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb512_mask, "ULLiV64cV64cULLi", "ncV:512:", "avx512bitalg")
+
+TARGET_BUILTIN(__builtin_ia32_pmulhrsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmulhuw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmulhw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
+
+TARGET_BUILTIN(__builtin_ia32_addpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_addps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_divpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_divps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_mulpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_mulps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_subpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_subps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
+
+TARGET_BUILTIN(__builtin_ia32_pmaddubsw512, "V32sV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmaddwd512, "V16iV32sV32s", "ncV:512:", "avx512bw")
+
+TARGET_BUILTIN(__builtin_ia32_addss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_divss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_mulss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_subss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_maxss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_minss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_addsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_divsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_mulsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_subsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_maxsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_minsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+
+TARGET_BUILTIN(__builtin_ia32_compressdf128_mask, "V2dV2dV2dUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compressdf256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compressdi128_mask, "V2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compressdi256_mask, "V4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl")
+
+TARGET_BUILTIN(__builtin_ia32_compresshi128_mask, "V8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_compresshi256_mask, "V16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_compressqi128_mask, "V16cV16cV16cUs", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_compressqi256_mask, "V32cV32cV32cUi", "ncV:256:", "avx512vl,avx512vbmi2")
+
+TARGET_BUILTIN(__builtin_ia32_compresssf128_mask, "V4fV4fV4fUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compresssf256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compresssi128_mask, "V4iV4iV4iUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compresssi256_mask, "V8iV8iV8iUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compressstoredf128_mask, "vV2d*V2dUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compressstoredf256_mask, "vV4d*V4dUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compressstoredi128_mask, "vV2LLi*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compressstoredi256_mask, "vV4LLi*V4LLiUc", "nV:256:", "avx512vl")
+
+TARGET_BUILTIN(__builtin_ia32_compressstorehi128_mask, "vV8s*V8sUc", "nV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_compressstorehi256_mask, "vV16s*V16sUs", "nV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_compressstoreqi128_mask, "vV16c*V16cUs", "nV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_compressstoreqi256_mask, "vV32c*V32cUi", "nV:256:", "avx512vl,avx512vbmi2")
+
+TARGET_BUILTIN(__builtin_ia32_compressstoresf128_mask, "vV4f*V4fUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compressstoresf256_mask, "vV8f*V8fUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compressstoresi128_mask, "vV4i*V4iUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_compressstoresi256_mask, "vV8i*V8iUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2dq128_mask, "V4iV2dV4iUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2ps_mask, "V4fV2dV4fUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2udq128_mask, "V4iV2dV4iUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2udq256_mask, "V4iV4dV4iUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtps2udq128_mask, "V4iV4fV4iUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtps2udq256_mask, "V8iV8fV8iUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2dq128_mask, "V4iV2dV4iUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2udq128_mask, "V4iV2dV4iUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2udq256_mask, "V4iV4dV4iUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvttps2udq128_mask, "V4iV4fV4iUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvttps2udq256_mask, "V8iV8fV8iUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expanddf128_mask, "V2dV2dV2dUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expanddf256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expanddi128_mask, "V2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expanddi256_mask, "V4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl")
+
+TARGET_BUILTIN(__builtin_ia32_expandhi128_mask, "V8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_expandhi256_mask, "V16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_expandqi128_mask, "V16cV16cV16cUs", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_expandqi256_mask, "V32cV32cV32cUi", "ncV:256:", "avx512vl,avx512vbmi2")
+
+TARGET_BUILTIN(__builtin_ia32_expandloaddf128_mask, "V2dV2dC*V2dUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expandloaddf256_mask, "V4dV4dC*V4dUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expandloaddi128_mask, "V4iV2LLiC*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expandloaddi256_mask, "V4LLiV4LLiC*V4LLiUc", "nV:256:", "avx512vl")
+
+TARGET_BUILTIN(__builtin_ia32_expandloadhi128_mask, "V8sV8sC*V8sUc", "nV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_expandloadhi256_mask, "V16sV16sC*V16sUs", "nV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_expandloadqi128_mask, "V16cV16cC*V16cUs", "nV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_expandloadqi256_mask, "V32cV32cC*V32cUi", "nV:256:", "avx512vl,avx512vbmi2")
+
+TARGET_BUILTIN(__builtin_ia32_expandloadsf128_mask, "V4fV4fC*V4fUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expandloadsf256_mask, "V8fV8fC*V8fUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expandloadsi128_mask, "V4iV4iC*V4iUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expandloadsi256_mask, "V8iV8iC*V8iUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expandsf128_mask, "V4fV4fV4fUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expandsf256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expandsi128_mask, "V4iV4iV4iUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_expandsi256_mask, "V8iV8iV8iUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_getexppd128_mask, "V2dV2dV2dUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_getexppd256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_getexpps128_mask, "V4fV4fV4fUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_getexpps256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pabsq128, "V2LLiV2LLi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pabsq256, "V4LLiV4LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmaxsq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmaxsq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmaxuq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmaxuq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pminsq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pminsq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pminuq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pminuq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rndscalepd_128_mask, "V2dV2dIiV2dUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rndscalepd_256_mask, "V4dV4dIiV4dUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rndscaleps_128_mask, "V4fV4fIiV4fUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rndscaleps_256_mask, "V8fV8fIiV8fUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scalefpd128_mask, "V2dV2dV2dV2dUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scalefpd256_mask, "V4dV4dV4dV4dUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scalefps128_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scalefps256_mask, "V8fV8fV8fV8fUc", "ncV:256:", "avx512vl")
+
+TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vd*UcV2LLiV2dIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vLLi*UcV2LLiV2LLiIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vd*UcV4LLiV4dIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vLLi*UcV4LLiV4LLiIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vf*UcV2LLiV4fIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vi*UcV2LLiV4iIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vf*UcV4LLiV4fIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vi*UcV4LLiV4iIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vd*UcV4iV2dIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vLLi*UcV4iV2LLiIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vd*UcV4iV4dIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vLLi*UcV4iV4LLiIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vf*UcV4iV4fIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vi*UcV4iV4iIi", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vf*UcV8iV8fIi", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vi*UcV8iV8iIi", "nV:256:", "avx512vl")
+
+TARGET_BUILTIN(__builtin_ia32_vpermi2vard128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpermi2vard256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpermi2vard512, "V16iV16iV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varpd128, "V2dV2dV2LLiV2d", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varpd256, "V4dV4dV4LLiV4d", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varpd512, "V8dV8dV8LLiV8d", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varps128, "V4fV4fV4iV4f", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varps256, "V8fV8fV8iV8f", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varps512, "V16fV16fV16iV16f", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varqi128, "V16cV16cV16cV16c", "ncV:128:", "avx512vbmi,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varqi256, "V32cV32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varqi512, "V64cV64cV64cV64c", "ncV:512:", "avx512vbmi")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varhi128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varhi256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varhi512, "V32sV32sV32sV32s", "ncV:512:", "avx512bw")
+
+TARGET_BUILTIN(__builtin_ia32_vpshldd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldd512, "V16iV16iV16iIi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldq128, "V2LLiV2LLiV2LLiIi", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldq256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldq512, "V8LLiV8LLiV8LLiIi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2")
+
+TARGET_BUILTIN(__builtin_ia32_vpshldvd128_mask, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd256_mask, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd512_mask, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw128_mask, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw256_mask, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd128_maskz, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd256_maskz, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd512_maskz, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw128_maskz, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw256_maskz, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw512_maskz, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
+
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_mask, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_mask, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_mask, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_mask, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_mask, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_maskz, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_maskz, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_maskz, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_maskz, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_maskz, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_maskz, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
+
+TARGET_BUILTIN(__builtin_ia32_vpshrdd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdd512, "V16iV16iV16iIi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdq128, "V2LLiV2LLiV2LLiIi", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdq256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdq512, "V8LLiV8LLiV8LLiIi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2")
+
+TARGET_BUILTIN(__builtin_ia32_pmovswb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovuswb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovwb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2qq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2qq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtps2qq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtps2qq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtps2uqq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtps2uqq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtqq2ps128_mask, "V4fV2LLiV4fUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtqq2ps256_mask, "V4fV4LLiV4fUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2qq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2qq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvttps2qq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvttps2qq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvttps2uqq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvttps2uqq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps128_mask, "V4fV2LLiV4fUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps256_mask, "V4fV4LLiV4fUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_rangepd128_mask, "V2dV2dV2dIiV2dUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_rangepd256_mask, "V4dV4dV4dIiV4dUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_rangeps128_mask, "V4fV4fV4fIiV4fUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_rangeps256_mask, "V8fV8fV8fIiV8fUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_rangesd128_round_mask, "V2dV2dV2dV2dUcIiIi", "ncV:128:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_rangess128_round_mask, "V4fV4fV4fV4fUcIiIi", "ncV:128:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_reducepd128_mask, "V2dV2dIiV2dUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_reducepd256_mask, "V4dV4dIiV4dUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_reduceps128_mask, "V4fV4fIiV4fUc", "ncV:128:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_reduceps256_mask, "V8fV8fIiV8fUc", "ncV:256:", "avx512vl,avx512dq")
+TARGET_BUILTIN(__builtin_ia32_reducesd_mask, "V2dV2dV2dV2dUcIiIi", "ncV:128:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_reducess_mask, "V4fV4fV4fV4fUcIiIi", "ncV:128:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_pmovswb128_mask, "V16cV8sV16cUc", "ncV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovswb256_mask, "V16cV16sV16cUs", "ncV:256:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovuswb128_mask, "V16cV8sV16cUc", "ncV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovuswb256_mask, "V16cV16sV16cUs", "ncV:256:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovwb128_mask, "V16cV8sV16cUc", "ncV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtps2qq512_mask, "V8LLiV8fV8LLiUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtps2uqq512_mask, "V8LLiV8fV8LLiUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtqq2pd512_mask, "V8dV8LLiV8dUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtqq2ps512_mask, "V8fV8LLiV8fUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvttps2qq512_mask, "V8LLiV8fV8LLiUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvttps2uqq512_mask, "V8LLiV8fV8LLiUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd512_mask, "V8dV8LLiV8dUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps512_mask, "V8fV8LLiV8fUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_rangepd512_mask, "V8dV8dV8dIiV8dUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_rangeps512_mask, "V16fV16fV16fIiV16fUsIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_reducepd512_mask, "V8dV8dIiV8dUcIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_reduceps512_mask, "V16fV16fIiV16fUsIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_prold512, "V16iV16iIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_prolq512, "V8LLiV8LLiIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_prold128, "V4iV4iIi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prold256, "V8iV8iIi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prolq128, "V2LLiV2LLiIi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prolq256, "V4LLiV4LLiIi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prolvd512, "V16iV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_prolvq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_prord512, "V16iV16iIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_prorq512, "V8LLiV8LLiIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_prolvd128, "V4iV4iV4i", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prolvd256, "V8iV8iV8i", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prolvq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prolvq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prord128, "V4iV4iIi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prord256, "V8iV8iIi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prorq128, "V2LLiV2LLiIi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prorq256, "V4LLiV4LLiIi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prorvd512, "V16iV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_prorvq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_prorvd128, "V4iV4iV4i", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prorvd256, "V8iV8iV8i", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prorvq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_prorvq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pshufhw512, "V32sV32sIi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pshuflw512, "V32sV32sIi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psllv32hi, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psllw512, "V32sV32sV8s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psllwi512, "V32sV32si", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psllv16hi, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psllv8hi, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pslldi512, "V16iV16ii", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psllqi512, "V8LLiV8LLii", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrlv32hi, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psrlv16hi, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psrlv8hi, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psrldi512, "V16iV16ii", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrlqi512, "V8LLiV8LLii", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrav32hi, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psrav16hi, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psrav8hi, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psravq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psravq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psraw512, "V32sV32sV8s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psrawi512, "V32sV32si", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psrlw512, "V32sV32sV8s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psrlwi512, "V32sV32si", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pslldqi512_byteshift, "V8LLiV8LLiIi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psrldqi512_byteshift, "V8LLiV8LLiIi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_movdqa32load128_mask, "V4iV4i*V4iUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_movdqa32load256_mask, "V8iV8i*V8iUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_movdqa32load512_mask, "V16iV16iC*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_movdqa32store512_mask, "vV16i*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_movdqa64load512_mask, "V8LLiV8LLiC*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_movdqa64store512_mask, "vV8LLi*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_movdqa32store128_mask, "vV4i*V4iUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_movdqa32store256_mask, "vV8i*V8iUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_movdqa64load128_mask, "V2LLiV2LLiC*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_movdqa64load256_mask, "V4LLiV4LLiC*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_movdqa64store128_mask, "vV2LLi*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_movdqa64store256_mask, "vV4LLi*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512ifma")
+TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512ifma")
+TARGET_BUILTIN(__builtin_ia32_vpmadd52huq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512ifma,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpmadd52huq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512ifma,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpmadd52luq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512ifma,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpmadd52luq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512ifma,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcomisd, "iV2dV2dIiIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcomiss, "iV4fV4fIiIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kunpckdi, "ULLiULLiULLi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_kunpcksi, "UiUiUi", "nc", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_loaddquhi512_mask, "V32sV32s*V32sUi", "nV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_loaddquqi512_mask, "V64cV64c*V64cULLi", "nV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_mask, "V8dV8dV8dV8LLiIiUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_maskz, "V8dV8dV8dV8LLiIiUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_fixupimmps512_mask, "V16fV16fV16fV16iIiUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_fixupimmps512_maskz, "V16fV16fV16fV16iIiUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_fixupimmsd_mask, "V2dV2dV2dV2LLiIiUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_fixupimmsd_maskz, "V2dV2dV2dV2LLiIiUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_fixupimmss_mask, "V4fV4fV4fV4iIiUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_fixupimmss_maskz, "V4fV4fV4fV4iIiUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_getexpsd128_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_getexpss128_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_getmantsd_round_mask, "V2dV2dV2dIiV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_getmantss_round_mask, "V4fV4fV4fIiV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_loaddquhi128_mask, "V8sV8s*V8sUc", "nV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loaddquhi256_mask, "V16sV16s*V16sUs", "nV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loaddquqi128_mask, "V16cV16c*V16cUs", "nV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loaddquqi256_mask, "V32cV32c*V32cUi", "nV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_mask, "V2dV2dV2dV2LLiIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_maskz, "V2dV2dV2dV2LLiIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_mask, "V4dV4dV4dV4LLiIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_maskz, "V4dV4dV4dV4LLiIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fixupimmps128_mask, "V4fV4fV4fV4iIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fixupimmps128_maskz, "V4fV4fV4fV4iIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fixupimmps256_mask, "V8fV8fV8fV8iIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fixupimmps256_maskz, "V8fV8fV8fV8iIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loadapd128_mask, "V2dV2d*V2dUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loadsd128_mask, "V2dV2d*V2dUc", "nV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_loadapd256_mask, "V4dV4d*V4dUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loadaps128_mask, "V4fV4f*V4fUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loadss128_mask, "V4fV4f*V4fUc", "nV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_loadaps256_mask, "V8fV8f*V8fUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loaddqudi128_mask, "V2LLiV2LLi*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loaddqudi256_mask, "V4LLiV4LLi*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loaddqusi128_mask, "V4iV4i*V4iUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loaddqusi256_mask, "V8iV8i*V8iUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loadupd128_mask, "V2dV2d*V2dUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loadupd256_mask, "V4dV4d*V4dUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loadups128_mask, "V4fV4f*V4fUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_loadups256_mask, "V8fV8f*V8fUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storedquhi512_mask, "vV32s*V32sUi", "nV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_storedquqi512_mask, "vV64c*V64cULLi", "nV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_storedquhi128_mask, "vV8s*V8sUc", "nV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_storedquhi256_mask, "vV16s*V16sUs", "nV:256:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_storedquqi128_mask, "vV16c*V16cUs", "nV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_storedquqi256_mask, "vV32c*V32cUi", "nV:256:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_storeapd128_mask, "vV2d*V2dUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storesd128_mask, "vV2d*V2dUc", "nV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_storeapd256_mask, "vV4d*V4dUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storeaps128_mask, "vV4f*V4fUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storess128_mask, "vV4f*V4fUc", "nV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_storeaps256_mask, "vV8f*V8fUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storedqudi128_mask, "vV2LLi*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storedqudi256_mask, "vV4LLi*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storedqusi128_mask, "vV4i*V4iUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storedqusi256_mask, "vV8i*V8iUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storeupd128_mask, "vV2d*V2dUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storeupd256_mask, "vV4d*V4dUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storeups128_mask, "vV4f*V4fUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_storeups256_mask, "vV8f*V8fUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rcp14pd128_mask, "V2dV2dV2dUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rcp14pd256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rcp14ps128_mask, "V4fV4fV4fUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rcp14ps256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vplzcntd_128, "V4iV4i", "ncV:128:", "avx512cd,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vplzcntd_256, "V8iV8i", "ncV:256:", "avx512cd,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vplzcntq_128, "V2LLiV2LLi", "ncV:128:", "avx512cd,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vplzcntq_256, "V4LLiV4LLi", "ncV:256:", "avx512cd,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtsd2si32, "iV2dIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi32, "UiV2dIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtss2si32, "iV4fIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtss2usi32, "UiV4fIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvttsd2si32, "iV2dIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi32, "UiV2dIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvttss2si32, "iV4fIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvttss2usi32, "UiV4fIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermilpd512, "V8dV8dIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermilps512, "V16fV16fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512, "V8dV8dV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermilvarps512, "V16fV16fV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rndscalesd_round_mask, "V2dV2dV2dV2dUcIiIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rndscaless_round_mask, "V4fV4fV4fV4fUcIiIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scalefpd512_mask, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scalefps512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scalefsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scalefss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psradi512, "V16iV16ii", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psraqi512, "V8LLiV8LLii", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psraq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psraq256, "V4LLiV4LLiV2LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psraqi128, "V2LLiV2LLii", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_psraqi256, "V4LLiV4LLii", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pslld512, "V16iV16iV4i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psllq512, "V8LLiV8LLiV2LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psllv16si, "V16iV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psllv8di, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrad512, "V16iV16iV4i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psraq512, "V8LLiV8LLiV2LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrav16si, "V16iV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrav8di, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrld512, "V16iV16iV4i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrlq512, "V8LLiV8LLiV2LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrlv16si, "V16iV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psrlv8di, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pternlogd512_mask, "V16iV16iV16iV16iIiUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pternlogd512_maskz, "V16iV16iV16iV16iIiUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pternlogq512_mask, "V8LLiV8LLiV8LLiV8LLiIiUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pternlogq512_maskz, "V8LLiV8LLiV8LLiV8LLiIiUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pternlogd128_mask, "V4iV4iV4iV4iIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pternlogd128_maskz, "V4iV4iV4iV4iIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pternlogd256_mask, "V8iV8iV8iV8iIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pternlogd256_maskz, "V8iV8iV8iV8iIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pternlogq128_mask, "V2LLiV2LLiV2LLiV2LLiIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pternlogq128_maskz, "V2LLiV2LLiV2LLiV2LLiIiUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pternlogq256_mask, "V4LLiV4LLiV4LLiV4LLiIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pternlogq256_maskz, "V4LLiV4LLiV4LLiV4LLiIiUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_shuf_f32x4, "V16fV16fV16fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_shuf_f64x2, "V8dV8dV8dIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_shuf_i32x4, "V16iV16iV16iIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_shuf_i64x2, "V8LLiV8LLiV8LLiIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_shufpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_shufps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_shuf_f32x4_256, "V8fV8fV8fIi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_shuf_f64x2_256, "V4dV4dV4dIi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_shuf_i32x4_256, "V8iV8iV8iIi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_shuf_i64x2_256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_sqrtsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_sqrtss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rsqrt14pd128_mask, "V2dV2dV2dUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rsqrt14pd256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rsqrt14ps128_mask, "V4fV4fV4fUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rsqrt14ps256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtb2mask512, "ULLiV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2b512, "V64cULLi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2w512, "V32sUi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cvtd2mask512, "UsV16i", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2d512, "V16iUs", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2q512, "V8LLiUc", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtq2mask512, "UcV8LLi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtb2mask128, "UsV16c", "ncV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtb2mask256, "UiV32c", "ncV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2b128, "V16cUs", "ncV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2b256, "V32cUi", "ncV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2w128, "V8sUc", "ncV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2w256, "V16sUs", "ncV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtd2mask128, "UcV4i", "ncV:128:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtd2mask256, "UcV8i", "ncV:256:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2d128, "V4iUc", "ncV:128:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2d256, "V8iUc", "ncV:256:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2q128, "V2LLiUc", "ncV:128:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2q256, "V4LLiUc", "ncV:256:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2LLi", "ncV:128:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4LLi", "ncV:256:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovsdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovswb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovsdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovsdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovsqb512_mask, "V16cV8LLiV16cUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovsqb512mem_mask, "vV16c*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovsqd512_mask, "V8iV8LLiV8iUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovsqd512mem_mask, "vV8i*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovsqw512_mask, "V8sV8LLiV8sUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovsqw512mem_mask, "vV8s*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovsdb128_mask, "V16cV4iV16cUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsdb128mem_mask, "vV16c*V4iUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovswb128mem_mask, "vV16c*V8sUc", "nV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovsdb256_mask, "V16cV8iV16cUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsdb256mem_mask, "vV16c*V8iUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovswb256mem_mask, "vV16c*V16sUs", "nV:256:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovsdw128_mask, "V8sV4iV8sUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsdw128mem_mask, "vV8s*V4iUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsdw256_mask, "V8sV8iV8sUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsdw256mem_mask, "vV8s*V8iUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsqb128_mask, "V16cV2LLiV16cUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsqb128mem_mask, "vV16c*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsqb256_mask, "V16cV4LLiV16cUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsqb256mem_mask, "vV16c*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsqd128_mask, "V4iV2LLiV4iUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsqd128mem_mask, "vV4i*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsqd256_mask, "V4iV4LLiV4iUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsqd256mem_mask, "vV4i*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsqw128_mask, "V8sV2LLiV8sUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsqw128mem_mask, "vV8s*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsqw256_mask, "V8sV4LLiV8sUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovsqw256mem_mask, "vV8s*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovusdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovuswb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovusdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovusdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovusqb512_mask, "V16cV8LLiV16cUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovusqb512mem_mask, "vV16c*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovusqd512_mask, "V8iV8LLiV8iUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovusqd512mem_mask, "vV8i*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovusqw512_mask, "V8sV8LLiV8sUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovusqw512mem_mask, "vV8s*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovusdb128_mask, "V16cV4iV16cUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusdb128mem_mask, "vV16c*V4iUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovuswb128mem_mask, "vV16c*V8sUc", "nV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovusdb256_mask, "V16cV8iV16cUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusdb256mem_mask, "vV16c*V8iUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovuswb256mem_mask, "vV16c*V16sUs", "nV:256:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovusdw128_mask, "V8sV4iV8sUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusdw128mem_mask, "vV8s*V4iUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusdw256_mask, "V8sV8iV8sUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusdw256mem_mask, "vV8s*V8iUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusqb128_mask, "V16cV2LLiV16cUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusqb128mem_mask, "vV16c*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusqb256_mask, "V16cV4LLiV16cUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusqb256mem_mask, "vV16c*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusqd128_mask, "V4iV2LLiV4iUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusqd128mem_mask, "vV4i*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusqd256_mask, "V4iV4LLiV4iUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusqd256mem_mask, "vV4i*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusqw128_mask, "V8sV2LLiV8sUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusqw128mem_mask, "vV8s*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusqw256_mask, "V8sV4LLiV8sUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovusqw256mem_mask, "vV8s*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovwb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovqb512_mask, "V16cV8LLiV16cUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovqb512mem_mask, "vV16c*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovqd512_mask, "V8iV8LLiV8iUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovqd512mem_mask, "vV8i*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovqw512_mask, "V8sV8LLiV8sUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovqw512mem_mask, "vV8s*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovdb128_mask, "V16cV4iV16cUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovwb128mem_mask, "vV16c*V8sUc", "nV:128:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovdb128mem_mask, "vV16c*V4iUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovdb256_mask, "V16cV8iV16cUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovdb256mem_mask, "vV16c*V8iUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovwb256mem_mask, "vV16c*V16sUs", "nV:256:", "avx512vl,avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovdw128_mask, "V8sV4iV8sUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovdw128mem_mask, "vV8s*V4iUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovdw256_mask, "V8sV8iV8sUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovdw256mem_mask, "vV8s*V8iUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovqb128_mask, "V16cV2LLiV16cUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovqb128mem_mask, "vV16c*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovqb256_mask, "V16cV4LLiV16cUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovqb256mem_mask, "vV16c*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovqd128_mask, "V4iV2LLiV4iUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovqd128mem_mask, "vV4i*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovqd256mem_mask, "vV4i*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovqw128_mask, "V8sV2LLiV8sUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovqw128mem_mask, "vV8s*V2LLiUc", "nV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovqw256_mask, "V8sV4LLiV8sUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_pmovqw256mem_mask, "vV8s*V4LLiUc", "nV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_extractf32x8_mask, "V8fV16fIiV8fUc", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_extractf64x2_512_mask, "V2dV8dIiV2dUc", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_extracti32x8_mask, "V8iV16iIiV8iUc", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_extracti64x2_512_mask, "V2LLiV8LLiIiV2LLiUc", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_extracti32x4_mask, "V4iV16iIiV4iUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_extracti64x4_mask, "V4LLiV8LLiIiV4LLiUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_extractf64x2_256_mask, "V2dV4dIiV2dUc", "ncV:256:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_extracti64x2_256_mask, "V2LLiV4LLiIiV2LLiUc", "ncV:256:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_extractf32x4_256_mask, "V4fV8fIiV4fUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_extracti32x4_256_mask, "V4iV8iIiV4iUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_insertf32x8, "V16fV16fV8fIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_insertf64x2_512, "V8dV8dV2dIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_inserti32x8, "V16iV16iV8iIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_inserti64x2_512, "V8LLiV8LLiV2LLiIi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_insertf64x4, "V8dV8dV4dIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_inserti64x4, "V8LLiV8LLiV4LLiIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_insertf64x2_256, "V4dV4dV2dIi", "ncV:256:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_inserti64x2_256, "V4LLiV4LLiV2LLiIi", "ncV:256:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_insertf32x4_256, "V8fV8fV4fIi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_inserti32x4_256, "V8iV8iV4iIi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_insertf32x4, "V16fV16fV4fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_inserti32x4, "V16iV16iV4iIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_getmantpd128_mask, "V2dV2dIiV2dUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_getmantpd256_mask, "V4dV4dIiV4dUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_getmantps128_mask, "V4fV4fIiV4fUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_getmantps256_mask, "V8fV8fIiV8fUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_getmantpd512_mask, "V8dV8dIiV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_getmantps512_mask, "V16fV16fIiV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_getexppd512_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_getexpps512_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddss3_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddss3_maskz, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddss3_mask3, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_maskz, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask3, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmsubsd3_mask3, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmsubss3_mask3, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_permdf512, "V8dV8dIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_permdi512, "V8LLiV8LLiIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_permvarhi512, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_permvardf512, "V8dV8dV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_permvardi512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_permvarsf512, "V16fV16fV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_permvarsi512, "V16iV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_permvarqi512, "V64cV64cV64c", "ncV:512:", "avx512vbmi")
+TARGET_BUILTIN(__builtin_ia32_permvarqi128, "V16cV16cV16c", "ncV:128:", "avx512vbmi,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_permvarqi256, "V32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_permvarhi128, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_permvarhi256, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_permvardf256, "V4dV4dV4LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_permvardi256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fpclasspd128_mask, "UcV2dIiUc", "ncV:128:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fpclasspd256_mask, "UcV4dIiUc", "ncV:256:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fpclassps128_mask, "UcV4fIiUc", "ncV:128:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fpclassps256_mask, "UcV8fIiUc", "ncV:256:", "avx512dq,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fpclassps512_mask, "UsV16fIiUs", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_fpclasspd512_mask, "UcV8dIiUc", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_fpclasssd_mask, "UcV2dIiUc", "ncV:128:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_fpclassss_mask, "UcV4fIiUc", "ncV:128:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_kandhi, "UsUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kandnhi, "UsUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_korhi, "UsUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kortestchi, "iUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kortestzhi, "iUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kunpckhi, "UsUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kxnorhi, "UsUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_kxorhi, "UsUsUs", "nc", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_palignr512, "V64cV64cV64cIi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_dbpsadbw128, "V8sV16cV16cIi", "ncV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_dbpsadbw256, "V16sV32cV32cIi", "ncV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_dbpsadbw512, "V32sV64cV64cIi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psadbw512, "V8LLiV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_compressdf512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_compressdi512_mask, "V8LLiV8LLiV8LLiUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_compresshi512_mask, "V32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_compressqi512_mask, "V64cV64cV64cULLi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_compresssf512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_compresssi512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cmpsd_mask, "UcV2dV2dIiUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cmpss_mask, "UcV4fV4fIiUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pshufd512, "V16iV16iIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_expanddf512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_expanddi512_mask, "V8LLiV8LLiV8LLiUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_expandhi512_mask, "V32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_expandqi512_mask, "V64cV64cV64cULLi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_expandloaddf512_mask, "V8dV8dC*V8dUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_expandloaddi512_mask, "V8LLiV8LLiC*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_expandloadhi512_mask, "V32sV32sC*V32sUi", "nV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_expandloadqi512_mask, "V64cV64cC*V64cULLi", "nV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_expandloadsf512_mask, "V16fV16fC*V16fUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_expandloadsi512_mask, "V16iV16iC*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_expandsf512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_expandsi512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtps2pd512_mask, "V8dV8fV8dUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_compressstoredf512_mask, "vV8d*V8dUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_compressstoredi512_mask, "vV8LLi*V8LLiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_compressstorehi512_mask, "vV32s*V32sUi", "nV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_compressstoreqi512_mask, "vV64c*V64cULLi", "nV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_compressstoresf512_mask, "vV16f*V16fUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_compressstoresi512_mask, "vV16i*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2ps_mask, "V4fV8sV4fUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2ps256_mask, "V8fV8sV8fUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtps2ph_mask, "V8sV4fIiV8sUc", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtps2ph256_mask, "V8sV8fIiV8sUc", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtw2mask512, "UiV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cvtw2mask128, "UcV8s", "ncV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtw2mask256, "UsV16s", "ncV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtsd2ss_round_mask, "V4fV4fV2dV4fUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtsi2ss32, "V4fV4fiIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtss2sd_round_mask, "V2dV2dV4fV2dUcIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtusi2ss32, "V4fV4fUiIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512vbmi")
+TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128_mask, "V16cV16cV16cV16cUs", "ncV:128:", "avx512vbmi,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256_mask, "V32cV32cV32cV32cUi", "ncV:256:", "avx512vbmi,avx512vl")
// generic select intrinsics
-TARGET_BUILTIN(__builtin_ia32_selectb_128, "V16cUsV16cV16c", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectb_256, "V32cUiV32cV32c", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectb_512, "V64cULLiV64cV64c", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectw_128, "V8sUcV8sV8s", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectw_256, "V16sUsV16sV16s", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectw_512, "V32sUiV32sV32s", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectd_128, "V4iUcV4iV4i", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectd_256, "V8iUcV8iV8i", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectd_512, "V16iUsV16iV16i", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectq_128, "V2LLiUcV2LLiV2LLi", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectq_256, "V4LLiUcV4LLiV4LLi", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectq_512, "V8LLiUcV8LLiV8LLi", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectps_128, "V4fUcV4fV4f", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectps_256, "V8fUcV8fV8f", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectps_512, "V16fUsV16fV16f", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectpd_128, "V2dUcV2dV2d", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectpd_256, "V4dUcV4dV4d", "", "")
-TARGET_BUILTIN(__builtin_ia32_selectpd_512, "V8dUcV8dV8d", "", "")
+TARGET_BUILTIN(__builtin_ia32_selectb_128, "V16cUsV16cV16c", "ncV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectb_256, "V32cUiV32cV32c", "ncV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectb_512, "V64cULLiV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_selectw_128, "V8sUcV8sV8s", "ncV:128:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectw_256, "V16sUsV16sV16s", "ncV:256:", "avx512bw,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectw_512, "V32sUiV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_selectd_128, "V4iUcV4iV4i", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectd_256, "V8iUcV8iV8i", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectd_512, "V16iUsV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_selectq_128, "V2LLiUcV2LLiV2LLi", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectq_256, "V4LLiUcV4LLiV4LLi", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectq_512, "V8LLiUcV8LLiV8LLi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_selectps_128, "V4fUcV4fV4f", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectps_256, "V8fUcV8fV8f", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectps_512, "V16fUsV16fV16f", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_selectpd_128, "V2dUcV2dV2d", "ncV:128:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectpd_256, "V4dUcV4dV4d", "ncV:256:", "avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectpd_512, "V8dUcV8dV8d", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_selectss_128, "V4fUcV4fV4f", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_selectsd_128, "V2dUcV2dV2d", "ncV:128:", "avx512f")
// MONITORX/MWAITX
-TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx")
-TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx")
+TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "n", "mwaitx")
+TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "n", "mwaitx")
+
+// WAITPKG
+TARGET_BUILTIN(__builtin_ia32_umonitor, "vv*", "n", "waitpkg")
+TARGET_BUILTIN(__builtin_ia32_umwait, "UcUiUiUi", "n", "waitpkg")
+TARGET_BUILTIN(__builtin_ia32_tpause, "UcUiUiUi", "n", "waitpkg")
// CLZERO
-TARGET_BUILTIN(__builtin_ia32_clzero, "vv*", "", "clzero")
+TARGET_BUILTIN(__builtin_ia32_clzero, "vv*", "n", "clzero")
+
+// CLDEMOTE
+TARGET_BUILTIN(__builtin_ia32_cldemote, "vvC*", "n", "cldemote")
+
+// Direct Move
+TARGET_BUILTIN(__builtin_ia32_directstore_u32, "vUi*Ui", "n", "movdiri")
+TARGET_BUILTIN(__builtin_ia32_movdir64b, "vv*vC*", "n", "movdir64b")
+
+// PTWRITE
+TARGET_BUILTIN(__builtin_ia32_ptwrite32, "vUi", "n", "ptwrite")
+
+// INVPCID
+TARGET_BUILTIN(__builtin_ia32_invpcid, "vUiv*", "nc", "invpcid")
// MSVC
TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
@@ -1897,14 +1845,14 @@ TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES
TARGET_HEADER_BUILTIN(_ReadBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_WriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__emul, "LLiii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__emul, "LLiii", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__int2c, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__ud2, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__int2c, "v", "nhr", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__ud2, "v", "nhr", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__readfsbyte, "UcUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__readfsword, "UsUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
diff --git a/include/clang/Basic/BuiltinsX86_64.def b/include/clang/Basic/BuiltinsX86_64.def
index fe2c887c7e0f5..cc400c0697f91 100644
--- a/include/clang/Basic/BuiltinsX86_64.def
+++ b/include/clang/Basic/BuiltinsX86_64.def
@@ -27,8 +27,8 @@ TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_
TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_mul128, "LLiLLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_umul128, "ULLiULLiULLiULLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_mul128, "LLiLLiLLiLLi*", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_umul128, "ULLiULLiULLiULLi*", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
@@ -44,50 +44,62 @@ TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh",
TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "")
TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "")
-TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "", "sse")
-TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "LLiV2d", "", "sse2")
-TARGET_BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_rdfsbase64, "ULLi", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "", "fsgsbase")
-TARGET_BUILTIN(__builtin_ia32_fxrstor64, "vv*", "", "fxsr")
-TARGET_BUILTIN(__builtin_ia32_fxsave64, "vv*", "", "fxsr")
-TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "", "xsave")
-TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "", "xsave")
-TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "", "xsaveopt")
-TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "", "xsaves")
-TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec")
-TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "", "xsaves")
-TARGET_BUILTIN(__builtin_ia32_incsspq, "vULLi", "u", "shstk")
-TARGET_BUILTIN(__builtin_ia32_rdsspq, "ULLiULLi", "Un", "shstk")
-TARGET_BUILTIN(__builtin_ia32_wrssq, "vULLiv*", "", "shstk")
-TARGET_BUILTIN(__builtin_ia32_wrussq, "vULLiv*", "", "shstk")
-TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx")
-TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "")
-TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "", "")
-TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "", "rdseed")
-TARGET_BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "", "bmi")
-TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "", "bmi2")
-TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "", "tbm")
-TARGET_BUILTIN(__builtin_ia32_lwpins64, "UcULLiUiUi", "", "lwp")
-TARGET_BUILTIN(__builtin_ia32_lwpval64, "vULLiUiUi", "", "lwp")
-TARGET_BUILTIN(__builtin_ia32_vcvtsd2si64, "LLiV2dIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "ULLiV2dIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "LLiV4fIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvtss2usi64, "ULLiV4fIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvttsd2si64, "LLiV2dIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi64, "ULLiV2dIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvttss2si64, "LLiV4fIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_vcvttss2usi64, "ULLiV4fIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtsi2sd64, "V2dV2dLLiIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fLLiIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dULLiIi","","avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fULLiIi","","avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "ncV:128:", "sse")
+TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "LLiV2d", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_movnti64, "vLLi*LLi", "n", "sse2")
+TARGET_BUILTIN(__builtin_ia32_vec_ext_v2di, "LLiV2LLiIi", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_vec_set_v2di, "V2LLiV2LLiLLiIi", "ncV:128:", "sse4.1")
+TARGET_BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "nc", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_vec_ext_v4di, "LLiV4LLiIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_vec_set_v4di, "V4LLiV4LLiLLiIi", "ncV:256:", "avx")
+TARGET_BUILTIN(__builtin_ia32_rdfsbase32, "Ui", "n", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_rdfsbase64, "ULLi", "n", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_rdgsbase32, "Ui", "n", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "n", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_wrfsbase32, "vUi", "n", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "n", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_wrgsbase32, "vUi", "n", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "n", "fsgsbase")
+TARGET_BUILTIN(__builtin_ia32_fxrstor64, "vv*", "n", "fxsr")
+TARGET_BUILTIN(__builtin_ia32_fxsave64, "vv*", "n", "fxsr")
+TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "n", "xsave")
+TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "n", "xsave")
+TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "n", "xsaveopt")
+TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "n", "xsaves")
+TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "n", "xsavec")
+TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "n", "xsaves")
+TARGET_BUILTIN(__builtin_ia32_incsspq, "vULLi", "n", "shstk")
+TARGET_BUILTIN(__builtin_ia32_rdsspq, "ULLiULLi", "n", "shstk")
+TARGET_BUILTIN(__builtin_ia32_wrssq, "vULLiv*", "n", "shstk")
+TARGET_BUILTIN(__builtin_ia32_wrussq, "vULLiv*", "n", "shstk")
+TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "n", "adx")
+TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "n", "")
+TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "n", "")
+TARGET_BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "n", "rdrnd")
+TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "n", "rdseed")
+TARGET_BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "nc", "bmi")
+TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "nc", "bmi2")
+TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "nc", "bmi2")
+TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "nc", "bmi2")
+TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "nc", "tbm")
+TARGET_BUILTIN(__builtin_ia32_lwpins64, "UcULLiUiUi", "n", "lwp")
+TARGET_BUILTIN(__builtin_ia32_lwpval64, "vULLiUiUi", "n", "lwp")
+TARGET_BUILTIN(__builtin_ia32_vcvtsd2si64, "LLiV2dIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "ULLiV2dIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "LLiV4fIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtss2usi64, "ULLiV4fIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvttsd2si64, "LLiV2dIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi64, "ULLiV2dIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvttss2si64, "LLiV4fIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvttss2usi64, "ULLiV4fIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtsi2sd64, "V2dV2dLLiIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fLLiIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dULLiIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fULLiIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_directstore_u64, "vULi*ULi", "n", "movdiri")
+TARGET_BUILTIN(__builtin_ia32_ptwrite64, "vULLi", "n", "ptwrite")
#undef BUILTIN
#undef TARGET_BUILTIN
diff --git a/include/clang/Basic/CMakeLists.txt b/include/clang/Basic/CMakeLists.txt
index 821c405913c8b..15bed5adec9e1 100644
--- a/include/clang/Basic/CMakeLists.txt
+++ b/include/clang/Basic/CMakeLists.txt
@@ -43,6 +43,8 @@ clang_tablegen(AttrHasAttributeImpl.inc -gen-clang-attr-has-attribute-impl
# ARM NEON
clang_tablegen(arm_neon.inc -gen-arm-neon-sema
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE arm_neon.td
TARGET ClangARMNeon)
+clang_tablegen(arm_fp16.inc -gen-arm-neon-sema
+ SOURCE arm_fp16.td
+ TARGET ClangARMFP16)
diff --git a/include/clang/Basic/CapturedStmt.h b/include/clang/Basic/CapturedStmt.h
index c4a289b696dd9..324e1b1d3d093 100644
--- a/include/clang/Basic/CapturedStmt.h
+++ b/include/clang/Basic/CapturedStmt.h
@@ -13,9 +13,10 @@
namespace clang {
-/// \brief The different kinds of captured statement.
+/// The different kinds of captured statement.
enum CapturedRegionKind {
CR_Default,
+ CR_ObjCAtFinally,
CR_OpenMP
};
diff --git a/include/clang/Basic/CharInfo.h b/include/clang/Basic/CharInfo.h
index cc27bbb48e0d1..e6c5e90d346c6 100644
--- a/include/clang/Basic/CharInfo.h
+++ b/include/clang/Basic/CharInfo.h
@@ -1,4 +1,4 @@
-//===--- clang/Basic/CharInfo.h - Classifying ASCII Characters ------------===//
+//===--- clang/Basic/CharInfo.h - Classifying ASCII Characters --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -180,14 +180,15 @@ LLVM_READONLY inline char toUppercase(char c) {
/// Return true if this is a valid ASCII identifier.
///
-/// Note that this is a very simple check; it does not accept '$' or UCNs as
-/// valid identifier characters.
-LLVM_READONLY inline bool isValidIdentifier(StringRef S) {
- if (S.empty() || !isIdentifierHead(S[0]))
+/// Note that this is a very simple check; it does not accept UCNs as valid
+/// identifier characters.
+LLVM_READONLY inline bool isValidIdentifier(StringRef S,
+ bool AllowDollar = false) {
+ if (S.empty() || !isIdentifierHead(S[0], AllowDollar))
return false;
for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I)
- if (!isIdentifierBody(*I))
+ if (!isIdentifierBody(*I, AllowDollar))
return false;
return true;
diff --git a/include/clang/Basic/CommentOptions.h b/include/clang/Basic/CommentOptions.h
index 92419f91b741b..6cc9cf6b199c5 100644
--- a/include/clang/Basic/CommentOptions.h
+++ b/include/clang/Basic/CommentOptions.h
@@ -1,4 +1,4 @@
-//===--- CommentOptions.h - Options for parsing comments -----*- C++ -*-===//
+//===- CommentOptions.h - Options for parsing comments ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
-/// \brief Defines the clang::CommentOptions interface.
-///
+/// Defines the clang::CommentOptions interface.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_COMMENTOPTIONS_H
@@ -20,20 +20,20 @@
namespace clang {
-/// \brief Options for controlling comment parsing.
+/// Options for controlling comment parsing.
struct CommentOptions {
- typedef std::vector<std::string> BlockCommandNamesTy;
+ using BlockCommandNamesTy = std::vector<std::string>;
- /// \brief Command names to treat as block commands in comments.
+ /// Command names to treat as block commands in comments.
/// Should not include the leading backslash.
BlockCommandNamesTy BlockCommandNames;
- /// \brief Treat ordinary comments as documentation comments.
- bool ParseAllComments;
+ /// Treat ordinary comments as documentation comments.
+ bool ParseAllComments = false;
- CommentOptions() : ParseAllComments(false) { }
+ CommentOptions() = default;
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_BASIC_COMMENTOPTIONS_H
diff --git a/include/clang/Basic/Cuda.h b/include/clang/Basic/Cuda.h
index 1a0731c37a35f..24159e160f3fc 100644
--- a/include/clang/Basic/Cuda.h
+++ b/include/clang/Basic/Cuda.h
@@ -22,7 +22,9 @@ enum class CudaVersion {
CUDA_75,
CUDA_80,
CUDA_90,
- LATEST = CUDA_90,
+ CUDA_91,
+ CUDA_92,
+ LATEST = CUDA_92,
};
const char *CudaVersionToString(CudaVersion V);
@@ -44,6 +46,21 @@ enum class CudaArch {
SM_61,
SM_62,
SM_70,
+ SM_72,
+ GFX600,
+ GFX601,
+ GFX700,
+ GFX701,
+ GFX702,
+ GFX703,
+ GFX704,
+ GFX801,
+ GFX802,
+ GFX803,
+ GFX810,
+ GFX900,
+ GFX902,
+ LAST,
};
const char *CudaArchToString(CudaArch A);
@@ -64,6 +81,8 @@ enum class CudaVirtualArch {
COMPUTE_61,
COMPUTE_62,
COMPUTE_70,
+ COMPUTE_72,
+ COMPUTE_AMDGCN,
};
const char *CudaVirtualArchToString(CudaVirtualArch A);
diff --git a/include/clang/Basic/DebugInfoOptions.h b/include/clang/Basic/DebugInfoOptions.h
index e7ff4a662b630..037c813c6114f 100644
--- a/include/clang/Basic/DebugInfoOptions.h
+++ b/include/clang/Basic/DebugInfoOptions.h
@@ -28,7 +28,7 @@ enum DebugInfoKind {
/// forward decls for types that could be
/// replaced with forward decls in the source
/// code. For dynamic C++ classes type info
- /// is only emitted int the module that
+ /// is only emitted into the module that
/// contains the classe's vtable.
FullDebugInfo /// Generate complete debug info.
};
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index a7458d45618ee..5205b4c210a6f 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -1,4 +1,4 @@
-//===--- Diagnostic.h - C Language Family Diagnostic Handling ---*- C++ -*-===//
+//===- Diagnostic.h - C Language Family Diagnostic Handling -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
-/// \brief Defines the Diagnostic-related interfaces.
-///
+/// Defines the Diagnostic-related interfaces.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_DIAGNOSTIC_H
@@ -22,12 +22,13 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include <algorithm>
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstdint>
+#include <limits>
#include <list>
#include <map>
#include <memory>
@@ -44,15 +45,16 @@ class DiagnosticConsumer;
class IdentifierInfo;
class LangOptions;
class Preprocessor;
+class SourceManager;
class StoredDiagnostic;
namespace tok {
- enum TokenKind : unsigned short;
+enum TokenKind : unsigned short;
-} // end namespace tok
+} // namespace tok
-/// \brief Annotates a diagnostic with some code that should be
+/// Annotates a diagnostic with some code that should be
/// inserted, removed, or replaced to fix the problem.
///
/// This kind of hint should be used when we are certain that the
@@ -63,29 +65,29 @@ namespace tok {
/// compilation.
class FixItHint {
public:
- /// \brief Code that should be replaced to correct the error. Empty for an
+ /// Code that should be replaced to correct the error. Empty for an
/// insertion hint.
CharSourceRange RemoveRange;
- /// \brief Code in the specific range that should be inserted in the insertion
+ /// Code in the specific range that should be inserted in the insertion
/// location.
CharSourceRange InsertFromRange;
- /// \brief The actual code to insert at the insertion location, as a
+ /// The actual code to insert at the insertion location, as a
/// string.
std::string CodeToInsert;
- bool BeforePreviousInsertions;
+ bool BeforePreviousInsertions = false;
- /// \brief Empty code modification hint, indicating that no code
+ /// Empty code modification hint, indicating that no code
/// modification is known.
- FixItHint() : BeforePreviousInsertions(false) { }
+ FixItHint() = default;
bool isNull() const {
return !RemoveRange.isValid();
}
- /// \brief Create a code modification hint that inserts the given
+ /// Create a code modification hint that inserts the given
/// code string at a specific location.
static FixItHint CreateInsertion(SourceLocation InsertionLoc,
StringRef Code,
@@ -98,7 +100,7 @@ public:
return Hint;
}
- /// \brief Create a code modification hint that inserts the given
+ /// Create a code modification hint that inserts the given
/// code from \p FromRange at a specific location.
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
CharSourceRange FromRange,
@@ -111,7 +113,7 @@ public:
return Hint;
}
- /// \brief Create a code modification hint that removes the given
+ /// Create a code modification hint that removes the given
/// source range.
static FixItHint CreateRemoval(CharSourceRange RemoveRange) {
FixItHint Hint;
@@ -122,7 +124,7 @@ public:
return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange));
}
- /// \brief Create a code modification hint that replaces the given
+ /// Create a code modification hint that replaces the given
/// source range with the given code string.
static FixItHint CreateReplacement(CharSourceRange RemoveRange,
StringRef Code) {
@@ -138,7 +140,7 @@ public:
}
};
-/// \brief Concrete class used by the front-end to report problems and issues.
+/// Concrete class used by the front-end to report problems and issues.
///
/// This massages the diagnostics (e.g. handling things like "report warnings
/// as errors" and passes them off to the DiagnosticConsumer for reporting to
@@ -146,7 +148,7 @@ public:
/// SourceManager.
class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
public:
- /// \brief The level of the diagnostic, after it has been through mapping.
+ /// The level of the diagnostic, after it has been through mapping.
enum Level {
Ignored = DiagnosticIDs::Ignored,
Note = DiagnosticIDs::Note,
@@ -157,45 +159,88 @@ public:
};
enum ArgumentKind {
- ak_std_string, ///< std::string
- ak_c_string, ///< const char *
- ak_sint, ///< int
- ak_uint, ///< unsigned
- ak_tokenkind, ///< enum TokenKind : unsigned
- ak_identifierinfo, ///< IdentifierInfo
- ak_qualtype, ///< QualType
- ak_declarationname, ///< DeclarationName
- ak_nameddecl, ///< NamedDecl *
- ak_nestednamespec, ///< NestedNameSpecifier *
- ak_declcontext, ///< DeclContext *
- ak_qualtype_pair, ///< pair<QualType, QualType>
- ak_attr ///< Attr *
+ /// std::string
+ ak_std_string,
+
+ /// const char *
+ ak_c_string,
+
+ /// int
+ ak_sint,
+
+ /// unsigned
+ ak_uint,
+
+ /// enum TokenKind : unsigned
+ ak_tokenkind,
+
+ /// IdentifierInfo
+ ak_identifierinfo,
+
+ /// QualType
+ ak_qualtype,
+
+ /// DeclarationName
+ ak_declarationname,
+
+ /// NamedDecl *
+ ak_nameddecl,
+
+ /// NestedNameSpecifier *
+ ak_nestednamespec,
+
+ /// DeclContext *
+ ak_declcontext,
+
+ /// pair<QualType, QualType>
+ ak_qualtype_pair,
+
+ /// Attr *
+ ak_attr
};
- /// \brief Represents on argument value, which is a union discriminated
+ /// Represents on argument value, which is a union discriminated
/// by ArgumentKind, with a value.
- typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
+ using ArgumentValue = std::pair<ArgumentKind, intptr_t>;
private:
- unsigned char AllExtensionsSilenced; // Used by __extension__
- bool SuppressAfterFatalError; // Suppress diagnostics after a fatal error?
- bool SuppressAllDiagnostics; // Suppress all diagnostics.
- bool ElideType; // Elide common types of templates.
- bool PrintTemplateTree; // Print a tree when comparing templates.
- bool ShowColors; // Color printing is enabled.
- OverloadsShown ShowOverloads; // Which overload candidates to show.
- unsigned ErrorLimit; // Cap of # errors emitted, 0 -> no limit.
- unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
- // 0 -> no limit.
- unsigned ConstexprBacktraceLimit; // Cap on depth of constexpr evaluation
- // backtrace stack, 0 -> no limit.
+ // Used by __extension__
+ unsigned char AllExtensionsSilenced = 0;
+
+ // Suppress diagnostics after a fatal error?
+ bool SuppressAfterFatalError = true;
+
+ // Suppress all diagnostics.
+ bool SuppressAllDiagnostics = false;
+
+ // Elide common types of templates.
+ bool ElideType = true;
+
+ // Print a tree when comparing templates.
+ bool PrintTemplateTree = false;
+
+ // Color printing is enabled.
+ bool ShowColors = false;
+
+ // Which overload candidates to show.
+ OverloadsShown ShowOverloads = Ovl_All;
+
+ // Cap of # errors emitted, 0 -> no limit.
+ unsigned ErrorLimit = 0;
+
+ // Cap on depth of template backtrace stack, 0 -> no limit.
+ unsigned TemplateBacktraceLimit = 0;
+
+ // Cap on depth of constexpr evaluation backtrace stack, 0 -> no limit.
+ unsigned ConstexprBacktraceLimit = 0;
+
IntrusiveRefCntPtr<DiagnosticIDs> Diags;
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
- DiagnosticConsumer *Client;
+ DiagnosticConsumer *Client = nullptr;
std::unique_ptr<DiagnosticConsumer> Owner;
- SourceManager *SourceMgr;
+ SourceManager *SourceMgr = nullptr;
- /// \brief Mapping information for diagnostics.
+ /// Mapping information for diagnostics.
///
/// Mapping info is packed into four bits per diagnostic. The low three
/// bits are the mapping (an instance of diag::Severity), or zero if unset.
@@ -211,25 +256,38 @@ private:
public:
// "Global" configuration state that can actually vary between modules.
- unsigned IgnoreAllWarnings : 1; // Ignore all warnings: -w
- unsigned EnableAllWarnings : 1; // Enable all warnings.
- unsigned WarningsAsErrors : 1; // Treat warnings like errors.
- unsigned ErrorsAsFatal : 1; // Treat errors like fatal errors.
- unsigned SuppressSystemWarnings : 1; // Suppress warnings in system headers.
- diag::Severity ExtBehavior; // Map extensions to warnings or errors?
+
+ // Ignore all warnings: -w
+ unsigned IgnoreAllWarnings : 1;
+
+ // Enable all warnings.
+ unsigned EnableAllWarnings : 1;
+
+ // Treat warnings like errors.
+ unsigned WarningsAsErrors : 1;
+
+ // Treat errors like fatal errors.
+ unsigned ErrorsAsFatal : 1;
+
+ // Suppress warnings in system headers.
+ unsigned SuppressSystemWarnings : 1;
+
+ // Map extensions to warnings or errors?
+ diag::Severity ExtBehavior = diag::Severity::Ignored;
DiagState()
: IgnoreAllWarnings(false), EnableAllWarnings(false),
WarningsAsErrors(false), ErrorsAsFatal(false),
- SuppressSystemWarnings(false), ExtBehavior(diag::Severity::Ignored) {}
+ SuppressSystemWarnings(false) {}
- typedef llvm::DenseMap<unsigned, DiagnosticMapping>::iterator iterator;
- typedef llvm::DenseMap<unsigned, DiagnosticMapping>::const_iterator
- const_iterator;
+ using iterator = llvm::DenseMap<unsigned, DiagnosticMapping>::iterator;
+ using const_iterator =
+ llvm::DenseMap<unsigned, DiagnosticMapping>::const_iterator;
void setMapping(diag::kind Diag, DiagnosticMapping Info) {
DiagMap[Diag] = Info;
}
+
DiagnosticMapping lookupMapping(diag::kind Diag) const {
return DiagMap.lookup(Diag);
}
@@ -240,7 +298,7 @@ private:
const_iterator end() const { return DiagMap.end(); }
};
- /// \brief Keeps and automatically disposes all DiagStates that we create.
+ /// Keeps and automatically disposes all DiagStates that we create.
std::list<DiagState> DiagStates;
/// A mapping from files to the diagnostic states for those files. Lazily
@@ -249,12 +307,16 @@ private:
public:
/// Add an initial diagnostic state.
void appendFirst(DiagState *State);
+
/// Add a new latest state point.
void append(SourceManager &SrcMgr, SourceLocation Loc, DiagState *State);
+
/// Look up the diagnostic state at a given source location.
DiagState *lookup(SourceManager &SrcMgr, SourceLocation Loc) const;
+
/// Determine whether this map is empty.
bool empty() const { return Files.empty(); }
+
/// Clear out this map.
void clear() {
Files.clear();
@@ -262,13 +324,21 @@ private:
CurDiagStateLoc = SourceLocation();
}
+ /// Produce a debugging dump of the diagnostic state.
+ LLVM_DUMP_METHOD void dump(SourceManager &SrcMgr,
+ StringRef DiagName = StringRef()) const;
+
/// Grab the most-recently-added state point.
DiagState *getCurDiagState() const { return CurDiagState; }
+
/// Get the location at which a diagnostic state was last added.
SourceLocation getCurDiagStateLoc() const { return CurDiagStateLoc; }
private:
- /// \brief Represents a point in source where the diagnostic state was
+ friend class ASTReader;
+ friend class ASTWriter;
+
+ /// Represents a point in source where the diagnostic state was
/// modified because of a pragma.
///
/// 'Loc' can be null if the point represents the diagnostic state
@@ -276,8 +346,9 @@ private:
struct DiagStatePoint {
DiagState *State;
unsigned Offset;
+
DiagStatePoint(DiagState *State, unsigned Offset)
- : State(State), Offset(Offset) { }
+ : State(State), Offset(Offset) {}
};
/// Description of the diagnostic states and state transitions for a
@@ -287,11 +358,14 @@ private:
/// as looking up the DecomposedIncludedLoc for the FileID in the Files
/// map would give us this, but we cache it here for performance.
File *Parent = nullptr;
+
/// The offset of this file within its parent.
unsigned ParentOffset = 0;
+
/// Whether this file has any local (not imported from an AST file)
/// diagnostic state transitions.
bool HasLocalTransitions = false;
+
/// The points within the file where the state changes. There will always
/// be at least one of these (the state on entry to the file).
llvm::SmallVector<DiagStatePoint, 4> StateTransitions;
@@ -304,21 +378,20 @@ private:
/// The initial diagnostic state.
DiagState *FirstDiagState;
+
/// The current diagnostic state.
DiagState *CurDiagState;
+
/// The location at which the current diagnostic state was established.
SourceLocation CurDiagStateLoc;
/// Get the diagnostic state information for a file.
File *getFile(SourceManager &SrcMgr, FileID ID) const;
-
- friend class ASTReader;
- friend class ASTWriter;
};
DiagStateMap DiagStatesByLoc;
- /// \brief Keeps the DiagState that was active during each diagnostic 'push'
+ /// Keeps the DiagState that was active during each diagnostic 'push'
/// so we can get back at it when we 'pop'.
std::vector<DiagState *> DiagStateOnPushStack;
@@ -328,41 +401,44 @@ private:
void PushDiagStatePoint(DiagState *State, SourceLocation L);
- /// \brief Finds the DiagStatePoint that contains the diagnostic state of
+ /// Finds the DiagStatePoint that contains the diagnostic state of
/// the given source location.
DiagState *GetDiagStateForLoc(SourceLocation Loc) const {
return SourceMgr ? DiagStatesByLoc.lookup(*SourceMgr, Loc)
: DiagStatesByLoc.getCurDiagState();
}
- /// \brief Sticky flag set to \c true when an error is emitted.
+ /// Sticky flag set to \c true when an error is emitted.
bool ErrorOccurred;
- /// \brief Sticky flag set to \c true when an "uncompilable error" occurs.
+ /// Sticky flag set to \c true when an "uncompilable error" occurs.
/// I.e. an error that was not upgraded from a warning by -Werror.
bool UncompilableErrorOccurred;
- /// \brief Sticky flag set to \c true when a fatal error is emitted.
+ /// Sticky flag set to \c true when a fatal error is emitted.
bool FatalErrorOccurred;
- /// \brief Indicates that an unrecoverable error has occurred.
+ /// Indicates that an unrecoverable error has occurred.
bool UnrecoverableErrorOccurred;
- /// \brief Counts for DiagnosticErrorTrap to check whether an error occurred
+ /// Counts for DiagnosticErrorTrap to check whether an error occurred
/// during a parsing section, e.g. during parsing a function.
unsigned TrapNumErrorsOccurred;
unsigned TrapNumUnrecoverableErrorsOccurred;
- /// \brief The level of the last diagnostic emitted.
+ /// The level of the last diagnostic emitted.
///
/// This is used to emit continuation diagnostics with the same level as the
/// diagnostic that they follow.
DiagnosticIDs::Level LastDiagLevel;
- unsigned NumWarnings; ///< Number of warnings reported
- unsigned NumErrors; ///< Number of errors reported
+ /// Number of warnings reported
+ unsigned NumWarnings;
- /// \brief A function pointer that converts an opaque diagnostic
+ /// Number of errors reported
+ unsigned NumErrors;
+
+ /// A function pointer that converts an opaque diagnostic
/// argument to a strings.
///
/// This takes the modifiers and argument that was present in the diagnostic.
@@ -372,28 +448,29 @@ private:
/// avoid redundancy across arguments.
///
/// This is a hack to avoid a layering violation between libbasic and libsema.
- typedef void (*ArgToStringFnTy)(
+ using ArgToStringFnTy = void (*)(
ArgumentKind Kind, intptr_t Val,
StringRef Modifier, StringRef Argument,
ArrayRef<ArgumentValue> PrevArgs,
SmallVectorImpl<char> &Output,
void *Cookie,
ArrayRef<intptr_t> QualTypeVals);
- void *ArgToStringCookie;
+
+ void *ArgToStringCookie = nullptr;
ArgToStringFnTy ArgToStringFn;
- /// \brief ID of the "delayed" diagnostic, which is a (typically
+ /// ID of the "delayed" diagnostic, which is a (typically
/// fatal) diagnostic that had to be delayed because it was found
/// while emitting another diagnostic.
unsigned DelayedDiagID;
- /// \brief First string argument for the delayed diagnostic.
+ /// First string argument for the delayed diagnostic.
std::string DelayedDiagArg1;
- /// \brief Second string argument for the delayed diagnostic.
+ /// Second string argument for the delayed diagnostic.
std::string DelayedDiagArg2;
- /// \brief Optional flag value.
+ /// Optional flag value.
///
/// Some flags accept values, for instance: -Wframe-larger-than=<value> and
/// -Rpass=<value>. The content of this string is emitted after the flag name
@@ -402,23 +479,28 @@ private:
public:
explicit DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> Diags,
- DiagnosticOptions *DiagOpts,
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
DiagnosticConsumer *client = nullptr,
bool ShouldOwnClient = true);
DiagnosticsEngine(const DiagnosticsEngine &) = delete;
DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete;
~DiagnosticsEngine();
+ LLVM_DUMP_METHOD void dump() const { DiagStatesByLoc.dump(*SourceMgr); }
+ LLVM_DUMP_METHOD void dump(StringRef DiagName) const {
+ DiagStatesByLoc.dump(*SourceMgr, DiagName);
+ }
+
const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
return Diags;
}
- /// \brief Retrieve the diagnostic options.
+ /// Retrieve the diagnostic options.
DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; }
- typedef llvm::iterator_range<DiagState::const_iterator> diag_mapping_range;
+ using diag_mapping_range = llvm::iterator_range<DiagState::const_iterator>;
- /// \brief Get the current set of diagnostic mappings.
+ /// Get the current set of diagnostic mappings.
diag_mapping_range getDiagnosticMappings() const {
const DiagState &DS = *GetCurDiagState();
return diag_mapping_range(DS.begin(), DS.end());
@@ -427,18 +509,20 @@ public:
DiagnosticConsumer *getClient() { return Client; }
const DiagnosticConsumer *getClient() const { return Client; }
- /// \brief Determine whether this \c DiagnosticsEngine object own its client.
+ /// Determine whether this \c DiagnosticsEngine object own its client.
bool ownsClient() const { return Owner != nullptr; }
- /// \brief Return the current diagnostic client along with ownership of that
+ /// Return the current diagnostic client along with ownership of that
/// client.
std::unique_ptr<DiagnosticConsumer> takeClient() { return std::move(Owner); }
bool hasSourceManager() const { return SourceMgr != nullptr; }
+
SourceManager &getSourceManager() const {
assert(SourceMgr && "SourceManager not set!");
return *SourceMgr;
}
+
void setSourceManager(SourceManager *SrcMgr) {
assert(DiagStatesByLoc.empty() &&
"Leftover diag state from a different SourceManager.");
@@ -450,54 +534,54 @@ public:
// how diagnostics are emitted.
//
- /// \brief Copies the current DiagMappings and pushes the new copy
+ /// Copies the current DiagMappings and pushes the new copy
/// onto the top of the stack.
void pushMappings(SourceLocation Loc);
- /// \brief Pops the current DiagMappings off the top of the stack,
+ /// Pops the current DiagMappings off the top of the stack,
/// causing the new top of the stack to be the active mappings.
///
/// \returns \c true if the pop happens, \c false if there is only one
/// DiagMapping on the stack.
bool popMappings(SourceLocation Loc);
- /// \brief Set the diagnostic client associated with this diagnostic object.
+ /// Set the diagnostic client associated with this diagnostic object.
///
/// \param ShouldOwnClient true if the diagnostic object should take
/// ownership of \c client.
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true);
- /// \brief Specify a limit for the number of errors we should
+ /// Specify a limit for the number of errors we should
/// emit before giving up.
///
/// Zero disables the limit.
void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
- /// \brief Specify the maximum number of template instantiation
+ /// Specify the maximum number of template instantiation
/// notes to emit along with a given diagnostic.
void setTemplateBacktraceLimit(unsigned Limit) {
TemplateBacktraceLimit = Limit;
}
- /// \brief Retrieve the maximum number of template instantiation
+ /// Retrieve the maximum number of template instantiation
/// notes to emit along with a given diagnostic.
unsigned getTemplateBacktraceLimit() const {
return TemplateBacktraceLimit;
}
- /// \brief Specify the maximum number of constexpr evaluation
+ /// Specify the maximum number of constexpr evaluation
/// notes to emit along with a given diagnostic.
void setConstexprBacktraceLimit(unsigned Limit) {
ConstexprBacktraceLimit = Limit;
}
- /// \brief Retrieve the maximum number of constexpr evaluation
+ /// Retrieve the maximum number of constexpr evaluation
/// notes to emit along with a given diagnostic.
unsigned getConstexprBacktraceLimit() const {
return ConstexprBacktraceLimit;
}
- /// \brief When set to true, any unmapped warnings are ignored.
+ /// When set to true, any unmapped warnings are ignored.
///
/// If this and WarningsAsErrors are both set, then this one wins.
void setIgnoreAllWarnings(bool Val) {
@@ -507,7 +591,7 @@ public:
return GetCurDiagState()->IgnoreAllWarnings;
}
- /// \brief When set to true, any unmapped ignored warnings are no longer
+ /// When set to true, any unmapped ignored warnings are no longer
/// ignored.
///
/// If this and IgnoreAllWarnings are both set, then that one wins.
@@ -518,7 +602,7 @@ public:
return GetCurDiagState()->EnableAllWarnings;
}
- /// \brief When set to true, any warnings reported are issued as errors.
+ /// When set to true, any warnings reported are issued as errors.
void setWarningsAsErrors(bool Val) {
GetCurDiagState()->WarningsAsErrors = Val;
}
@@ -526,15 +610,15 @@ public:
return GetCurDiagState()->WarningsAsErrors;
}
- /// \brief When set to true, any error reported is made a fatal error.
+ /// When set to true, any error reported is made a fatal error.
void setErrorsAsFatal(bool Val) { GetCurDiagState()->ErrorsAsFatal = Val; }
bool getErrorsAsFatal() const { return GetCurDiagState()->ErrorsAsFatal; }
- /// \brief When set to true (the default), suppress further diagnostics after
+ /// When set to true (the default), suppress further diagnostics after
/// a fatal error.
void setSuppressAfterFatalError(bool Val) { SuppressAfterFatalError = Val; }
- /// \brief When set to true mask warnings that come from system headers.
+ /// When set to true mask warnings that come from system headers.
void setSuppressSystemWarnings(bool Val) {
GetCurDiagState()->SuppressSystemWarnings = Val;
}
@@ -542,7 +626,7 @@ public:
return GetCurDiagState()->SuppressSystemWarnings;
}
- /// \brief Suppress all diagnostics, to silence the front end when we
+ /// Suppress all diagnostics, to silence the front end when we
/// know that we don't want any more diagnostics to be passed along to the
/// client
void setSuppressAllDiagnostics(bool Val = true) {
@@ -550,22 +634,22 @@ public:
}
bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
- /// \brief Set type eliding, to skip outputting same types occurring in
+ /// Set type eliding, to skip outputting same types occurring in
/// template types.
void setElideType(bool Val = true) { ElideType = Val; }
bool getElideType() { return ElideType; }
- /// \brief Set tree printing, to outputting the template difference in a
+ /// Set tree printing, to outputting the template difference in a
/// tree format.
void setPrintTemplateTree(bool Val = false) { PrintTemplateTree = Val; }
bool getPrintTemplateTree() { return PrintTemplateTree; }
- /// \brief Set color printing, so the type diffing will inject color markers
+ /// Set color printing, so the type diffing will inject color markers
/// into the output.
void setShowColors(bool Val = false) { ShowColors = Val; }
bool getShowColors() { return ShowColors; }
- /// \brief Specify which overload candidates to show when overload resolution
+ /// Specify which overload candidates to show when overload resolution
/// fails.
///
/// By default, we show all candidates.
@@ -574,7 +658,7 @@ public:
}
OverloadsShown getShowOverloads() const { return ShowOverloads; }
- /// \brief Pretend that the last diagnostic issued was ignored, so any
+ /// Pretend that the last diagnostic issued was ignored, so any
/// subsequent notes will be suppressed, or restore a prior ignoring
/// state after ignoring some diagnostics and their notes, possibly in
/// the middle of another diagnostic.
@@ -586,14 +670,14 @@ public:
LastDiagLevel = Ignored ? DiagnosticIDs::Ignored : DiagnosticIDs::Warning;
}
- /// \brief Determine whether the previous diagnostic was ignored. This can
+ /// Determine whether the previous diagnostic was ignored. This can
/// be used by clients that want to determine whether notes attached to a
/// diagnostic will be suppressed.
bool isLastDiagnosticIgnored() const {
return LastDiagLevel == DiagnosticIDs::Ignored;
}
- /// \brief Controls whether otherwise-unmapped extension diagnostics are
+ /// Controls whether otherwise-unmapped extension diagnostics are
/// mapped onto ignore/warning/error.
///
/// This corresponds to the GCC -pedantic and -pedantic-errors option.
@@ -604,7 +688,7 @@ public:
return GetCurDiagState()->ExtBehavior;
}
- /// \brief Counter bumped when an __extension__ block is/ encountered.
+ /// Counter bumped when an __extension__ block is/ encountered.
///
/// When non-zero, all extension diagnostics are entirely silenced, no
/// matter how they are mapped.
@@ -612,7 +696,7 @@ public:
void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
- /// \brief This allows the client to specify that certain warnings are
+ /// This allows the client to specify that certain warnings are
/// ignored.
///
/// Notes can never be mapped, errors can only be mapped to fatal, and
@@ -622,7 +706,7 @@ public:
/// take affect. It can be null if we are setting the latest state.
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc);
- /// \brief Change an entire diagnostic group (e.g. "unknown-pragmas") to
+ /// Change an entire diagnostic group (e.g. "unknown-pragmas") to
/// have the specified mapping.
///
/// \returns true (and ignores the request) if "Group" was unknown, false
@@ -637,21 +721,21 @@ public:
diag::Severity Map,
SourceLocation Loc = SourceLocation());
- /// \brief Set the warning-as-error flag for the given diagnostic group.
+ /// Set the warning-as-error flag for the given diagnostic group.
///
/// This function always only operates on the current diagnostic state.
///
/// \returns True if the given group is unknown, false otherwise.
bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled);
- /// \brief Set the error-as-fatal flag for the given diagnostic group.
+ /// Set the error-as-fatal flag for the given diagnostic group.
///
/// This function always only operates on the current diagnostic state.
///
/// \returns True if the given group is unknown, false otherwise.
bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled);
- /// \brief Add the specified mapping to all diagnostics of the specified
+ /// Add the specified mapping to all diagnostics of the specified
/// flavor.
///
/// Mainly to be used by -Wno-everything to disable all warnings but allow
@@ -661,14 +745,14 @@ public:
bool hasErrorOccurred() const { return ErrorOccurred; }
- /// \brief Errors that actually prevent compilation, not those that are
+ /// Errors that actually prevent compilation, not those that are
/// upgraded from a warning by -Werror.
bool hasUncompilableErrorOccurred() const {
return UncompilableErrorOccurred;
}
bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
- /// \brief Determine whether any kind of unrecoverable error has occurred.
+ /// Determine whether any kind of unrecoverable error has occurred.
bool hasUnrecoverableErrorOccurred() const {
return FatalErrorOccurred || UnrecoverableErrorOccurred;
}
@@ -679,7 +763,7 @@ public:
this->NumWarnings = NumWarnings;
}
- /// \brief Return an ID for a diagnostic with the specified format string and
+ /// Return an ID for a diagnostic with the specified format string and
/// level.
///
/// If this is the first request for this diagnostic, it is registered and
@@ -693,7 +777,7 @@ public:
StringRef(FormatString, N - 1));
}
- /// \brief Converts a diagnostic argument (as an intptr_t) into the string
+ /// Converts a diagnostic argument (as an intptr_t) into the string
/// that represents it.
void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
StringRef Modifier, StringRef Argument,
@@ -709,13 +793,13 @@ public:
ArgToStringCookie = Cookie;
}
- /// \brief Note that the prior diagnostic was emitted by some other
+ /// Note that the prior diagnostic was emitted by some other
/// \c DiagnosticsEngine, and we may be attaching a note to that diagnostic.
void notePriorDiagnosticFrom(const DiagnosticsEngine &Other) {
LastDiagLevel = Other.LastDiagLevel;
}
- /// \brief Reset the state of the diagnostic object to its initial
+ /// Reset the state of the diagnostic object to its initial
/// configuration.
void Reset();
@@ -723,7 +807,7 @@ public:
// DiagnosticsEngine classification and reporting interfaces.
//
- /// \brief Determine whether the diagnostic is known to be ignored.
+ /// Determine whether the diagnostic is known to be ignored.
///
/// This can be used to opportunistically avoid expensive checks when it's
/// known for certain that the diagnostic has been suppressed at the
@@ -736,7 +820,7 @@ public:
diag::Severity::Ignored;
}
- /// \brief Based on the way the client configured the DiagnosticsEngine
+ /// Based on the way the client configured the DiagnosticsEngine
/// object, classify the specified diagnostic ID into a Level, consumable by
/// the DiagnosticConsumer.
///
@@ -750,7 +834,7 @@ public:
return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this);
}
- /// \brief Issue the message to the client.
+ /// Issue the message to the client.
///
/// This actually returns an instance of DiagnosticBuilder which emits the
/// diagnostics (through @c ProcessDiag) when it is destroyed.
@@ -763,10 +847,12 @@ public:
void Report(const StoredDiagnostic &storedDiag);
- /// \brief Determine whethere there is already a diagnostic in flight.
- bool isDiagnosticInFlight() const { return CurDiagID != ~0U; }
+ /// Determine whethere there is already a diagnostic in flight.
+ bool isDiagnosticInFlight() const {
+ return CurDiagID != std::numeric_limits<unsigned>::max();
+ }
- /// \brief Set the "delayed" diagnostic that will be emitted once
+ /// Set the "delayed" diagnostic that will be emitted once
/// the current diagnostic completes.
///
/// If a diagnostic is already in-flight but the front end must
@@ -790,38 +876,39 @@ public:
void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "",
StringRef Arg2 = "");
- /// \brief Clear out the current diagnostic.
- void Clear() { CurDiagID = ~0U; }
+ /// Clear out the current diagnostic.
+ void Clear() { CurDiagID = std::numeric_limits<unsigned>::max(); }
- /// \brief Return the value associated with this diagnostic flag.
+ /// Return the value associated with this diagnostic flag.
StringRef getFlagValue() const { return FlagValue; }
private:
- /// \brief Report the delayed diagnostic.
- void ReportDelayed();
-
// This is private state used by DiagnosticBuilder. We put it here instead of
// in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight
// object. This implementation choice means that we can only have one
// diagnostic "in flight" at a time, but this seems to be a reasonable
// tradeoff to keep these objects small. Assertions verify that only one
// diagnostic is in flight at a time.
- friend class DiagnosticIDs;
- friend class DiagnosticBuilder;
friend class Diagnostic;
- friend class PartialDiagnostic;
+ friend class DiagnosticBuilder;
friend class DiagnosticErrorTrap;
+ friend class DiagnosticIDs;
+ friend class PartialDiagnostic;
- /// \brief The location of the current diagnostic that is in flight.
+ /// Report the delayed diagnostic.
+ void ReportDelayed();
+
+ /// The location of the current diagnostic that is in flight.
SourceLocation CurDiagLoc;
- /// \brief The ID of the current diagnostic that is in flight.
+ /// The ID of the current diagnostic that is in flight.
///
- /// This is set to ~0U when there is no diagnostic in flight.
+ /// This is set to std::numeric_limits<unsigned>::max() when there is no
+ /// diagnostic in flight.
unsigned CurDiagID;
enum {
- /// \brief The maximum number of arguments we can hold.
+ /// The maximum number of arguments we can hold.
///
/// We currently only support up to 10 arguments (%0-%9). A single
/// diagnostic with more than that almost certainly has to be simplified
@@ -829,33 +916,33 @@ private:
MaxArguments = 10,
};
- /// \brief The number of entries in Arguments.
+ /// The number of entries in Arguments.
signed char NumDiagArgs;
- /// \brief Specifies whether an argument is in DiagArgumentsStr or
+ /// Specifies whether an argument is in DiagArgumentsStr or
/// in DiagArguments.
///
/// This is an array of ArgumentKind::ArgumentKind enum values, one for each
/// argument.
unsigned char DiagArgumentsKind[MaxArguments];
- /// \brief Holds the values of each string argument for the current
+ /// Holds the values of each string argument for the current
/// diagnostic.
///
/// This is only used when the corresponding ArgumentKind is ak_std_string.
std::string DiagArgumentsStr[MaxArguments];
- /// \brief The values for the various substitution positions.
+ /// The values for the various substitution positions.
///
/// This is used when the argument is not an std::string. The specific
/// value is mangled into an intptr_t and the interpretation depends on
/// exactly what sort of argument kind it is.
intptr_t DiagArgumentsVal[MaxArguments];
- /// \brief The list of ranges added to this diagnostic.
+ /// The list of ranges added to this diagnostic.
SmallVector<CharSourceRange, 8> DiagRanges;
- /// \brief If valid, provides a hint with some code to insert, remove,
+ /// If valid, provides a hint with some code to insert, remove,
/// or modify at a particular position.
SmallVector<FixItHint, 8> DiagFixItHints;
@@ -874,7 +961,7 @@ private:
return Mapping;
}
- /// \brief Used to report a diagnostic that is finally fully formed.
+ /// Used to report a diagnostic that is finally fully formed.
///
/// \returns true if the diagnostic was emitted, false if it was suppressed.
bool ProcessDiag() {
@@ -884,13 +971,16 @@ private:
/// @name Diagnostic Emission
/// @{
protected:
+ friend class ASTReader;
+ friend class ASTWriter;
+
// Sema requires access to the following functions because the current design
// of SFINAE requires it to use its own SemaDiagnosticBuilder, which needs to
// access us directly to ensure we minimize the emitted code for the common
// Sema::Diag() patterns.
friend class Sema;
- /// \brief Emit the current diagnostic and clear the diagnostic state.
+ /// Emit the current diagnostic and clear the diagnostic state.
///
/// \param Force Emit the diagnostic regardless of suppression settings.
bool EmitCurrentDiagnostic(bool Force = false);
@@ -900,12 +990,9 @@ protected:
SourceLocation getCurrentDiagLoc() const { return CurDiagLoc; }
/// @}
-
- friend class ASTReader;
- friend class ASTWriter;
};
-/// \brief RAII class that determines when any errors have occurred
+/// RAII class that determines when any errors have occurred
/// between the time the instance was created and the time it was
/// queried.
class DiagnosticErrorTrap {
@@ -915,21 +1002,21 @@ class DiagnosticErrorTrap {
public:
explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag)
- : Diag(Diag) { reset(); }
+ : Diag(Diag) { reset(); }
- /// \brief Determine whether any errors have occurred since this
+ /// Determine whether any errors have occurred since this
/// object instance was created.
bool hasErrorOccurred() const {
return Diag.TrapNumErrorsOccurred > NumErrors;
}
- /// \brief Determine whether any unrecoverable errors have occurred since this
+ /// Determine whether any unrecoverable errors have occurred since this
/// object instance was created.
bool hasUnrecoverableErrorOccurred() const {
return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors;
}
- /// \brief Set to initial state of "no errors occurred".
+ /// Set to initial state of "no errors occurred".
void reset() {
NumErrors = Diag.TrapNumErrorsOccurred;
NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred;
@@ -940,7 +1027,7 @@ public:
// DiagnosticBuilder
//===----------------------------------------------------------------------===//
-/// \brief A little helper class used to produce diagnostics.
+/// A little helper class used to produce diagnostics.
///
/// This is constructed by the DiagnosticsEngine::Report method, and
/// allows insertion of extra information (arguments and source ranges) into
@@ -953,22 +1040,23 @@ public:
/// the common fields to registers, eliminating increments of the NumArgs field,
/// for example.
class DiagnosticBuilder {
+ friend class DiagnosticsEngine;
+ friend class PartialDiagnostic;
+
mutable DiagnosticsEngine *DiagObj = nullptr;
mutable unsigned NumArgs = 0;
- /// \brief Status variable indicating if this diagnostic is still active.
+ /// Status variable indicating if this diagnostic is still active.
///
// NOTE: This field is redundant with DiagObj (IsActive iff (DiagObj == 0)),
// but LLVM is not currently smart enough to eliminate the null check that
// Emit() would end up with if we used that as our status variable.
mutable bool IsActive = false;
- /// \brief Flag indicating that this diagnostic is being emitted via a
+ /// Flag indicating that this diagnostic is being emitted via a
/// call to ForceEmit.
mutable bool IsForceEmit = false;
- friend class DiagnosticsEngine;
-
DiagnosticBuilder() = default;
explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
@@ -978,24 +1066,22 @@ class DiagnosticBuilder {
diagObj->DiagFixItHints.clear();
}
- friend class PartialDiagnostic;
-
protected:
void FlushCounts() {
DiagObj->NumDiagArgs = NumArgs;
}
- /// \brief Clear out the current diagnostic.
+ /// Clear out the current diagnostic.
void Clear() const {
DiagObj = nullptr;
IsActive = false;
IsForceEmit = false;
}
- /// \brief Determine whether this diagnostic is still active.
+ /// Determine whether this diagnostic is still active.
bool isActive() const { return IsActive; }
- /// \brief Force the diagnostic builder to emit the diagnostic now.
+ /// Force the diagnostic builder to emit the diagnostic now.
///
/// Once this function has been called, the DiagnosticBuilder object
/// should not be used again before it is destroyed.
@@ -1033,23 +1119,23 @@ public:
DiagnosticBuilder &operator=(const DiagnosticBuilder &) = delete;
- /// \brief Emits the diagnostic.
+ /// Emits the diagnostic.
~DiagnosticBuilder() {
Emit();
}
- /// \brief Retrieve an empty diagnostic builder.
+ /// Retrieve an empty diagnostic builder.
static DiagnosticBuilder getEmpty() {
- return DiagnosticBuilder();
+ return {};
}
- /// \brief Forces the diagnostic to be emitted.
+ /// Forces the diagnostic to be emitted.
const DiagnosticBuilder &setForceEmit() const {
IsForceEmit = true;
return *this;
}
- /// \brief Conversion of DiagnosticBuilder to bool always returns \c true.
+ /// Conversion of DiagnosticBuilder to bool always returns \c true.
///
/// This allows is to be used in boolean error contexts (where \c true is
/// used to indicate that an error has occurred), like:
@@ -1089,11 +1175,12 @@ public:
};
struct AddFlagValue {
- explicit AddFlagValue(StringRef V) : Val(V) {}
StringRef Val;
+
+ explicit AddFlagValue(StringRef V) : Val(V) {}
};
-/// \brief Register a value for the flag in the current diagnostic. This
+/// Register a value for the flag in the current diagnostic. This
/// value will be shown as the suffix "=value" after the flag name. It is
/// useful in cases where the diagnostic flag accepts values (e.g.,
/// -Rpass or -Wframe-larger-than).
@@ -1199,14 +1286,15 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
/// A nullability kind paired with a bit indicating whether it used a
/// context-sensitive keyword.
-typedef std::pair<NullabilityKind, bool> DiagNullabilityKind;
+using DiagNullabilityKind = std::pair<NullabilityKind, bool>;
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
DiagNullabilityKind nullability);
inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
unsigned DiagID) {
- assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
+ assert(CurDiagID == std::numeric_limits<unsigned>::max() &&
+ "Multiple diagnostics in flight at once!");
CurDiagLoc = Loc;
CurDiagID = DiagID;
FlagValue.clear();
@@ -1231,7 +1319,7 @@ class Diagnostic {
public:
explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {}
Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage)
- : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {}
+ : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {}
const DiagnosticsEngine *getDiags() const { return DiagObj; }
unsigned getID() const { return DiagObj->CurDiagID; }
@@ -1241,7 +1329,7 @@ public:
unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
- /// \brief Return the kind of the specified index.
+ /// Return the kind of the specified index.
///
/// Based on the kind of argument, the accessors below can be used to get
/// the value.
@@ -1252,7 +1340,7 @@ public:
return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
}
- /// \brief Return the provided argument string specified by \p Idx.
+ /// Return the provided argument string specified by \p Idx.
/// \pre getArgKind(Idx) == DiagnosticsEngine::ak_std_string
const std::string &getArgStdStr(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string &&
@@ -1260,7 +1348,7 @@ public:
return DiagObj->DiagArgumentsStr[Idx];
}
- /// \brief Return the specified C string argument.
+ /// Return the specified C string argument.
/// \pre getArgKind(Idx) == DiagnosticsEngine::ak_c_string
const char *getArgCStr(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string &&
@@ -1268,7 +1356,7 @@ public:
return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
}
- /// \brief Return the specified signed integer argument.
+ /// Return the specified signed integer argument.
/// \pre getArgKind(Idx) == DiagnosticsEngine::ak_sint
int getArgSInt(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
@@ -1276,7 +1364,7 @@ public:
return (int)DiagObj->DiagArgumentsVal[Idx];
}
- /// \brief Return the specified unsigned integer argument.
+ /// Return the specified unsigned integer argument.
/// \pre getArgKind(Idx) == DiagnosticsEngine::ak_uint
unsigned getArgUInt(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
@@ -1284,7 +1372,7 @@ public:
return (unsigned)DiagObj->DiagArgumentsVal[Idx];
}
- /// \brief Return the specified IdentifierInfo argument.
+ /// Return the specified IdentifierInfo argument.
/// \pre getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo
const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&
@@ -1292,7 +1380,7 @@ public:
return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
}
- /// \brief Return the specified non-string argument in an opaque form.
+ /// Return the specified non-string argument in an opaque form.
/// \pre getArgKind(Idx) != DiagnosticsEngine::ak_std_string
intptr_t getRawArg(unsigned Idx) const {
assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&
@@ -1300,7 +1388,7 @@ public:
return DiagObj->DiagArgumentsVal[Idx];
}
- /// \brief Return the number of source ranges associated with this diagnostic.
+ /// Return the number of source ranges associated with this diagnostic.
unsigned getNumRanges() const {
return DiagObj->DiagRanges.size();
}
@@ -1311,7 +1399,7 @@ public:
return DiagObj->DiagRanges[Idx];
}
- /// \brief Return an array reference for this diagnostic's ranges.
+ /// Return an array reference for this diagnostic's ranges.
ArrayRef<CharSourceRange> getRanges() const {
return DiagObj->DiagRanges;
}
@@ -1329,20 +1417,20 @@ public:
return DiagObj->DiagFixItHints;
}
- /// \brief Format this diagnostic into a string, substituting the
+ /// Format this diagnostic into a string, substituting the
/// formal arguments into the %0 slots.
///
/// The result is appended onto the \p OutStr array.
void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const;
- /// \brief Format the given format-string into the output buffer using the
+ /// Format the given format-string into the output buffer using the
/// arguments stored in this diagnostic.
void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
SmallVectorImpl<char> &OutStr) const;
};
/**
- * \brief Represents a diagnostic in a form that can be retained until its
+ * Represents a diagnostic in a form that can be retained until its
* corresponding source manager is destroyed.
*/
class StoredDiagnostic {
@@ -1363,7 +1451,7 @@ public:
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> Fixits);
- /// \brief Evaluates true when this object stores a diagnostic.
+ /// Evaluates true when this object stores a diagnostic.
explicit operator bool() const { return !Message.empty(); }
unsigned getID() const { return ID; }
@@ -1373,7 +1461,8 @@ public:
void setLocation(FullSourceLoc Loc) { this->Loc = Loc; }
- typedef std::vector<CharSourceRange>::const_iterator range_iterator;
+ using range_iterator = std::vector<CharSourceRange>::const_iterator;
+
range_iterator range_begin() const { return Ranges.begin(); }
range_iterator range_end() const { return Ranges.end(); }
unsigned range_size() const { return Ranges.size(); }
@@ -1382,7 +1471,8 @@ public:
return llvm::makeArrayRef(Ranges);
}
- typedef std::vector<FixItHint>::const_iterator fixit_iterator;
+ using fixit_iterator = std::vector<FixItHint>::const_iterator;
+
fixit_iterator fixit_begin() const { return FixIts.begin(); }
fixit_iterator fixit_end() const { return FixIts.end(); }
unsigned fixit_size() const { return FixIts.size(); }
@@ -1392,7 +1482,7 @@ public:
}
};
-/// \brief Abstract interface, implemented by clients of the front-end, which
+/// Abstract interface, implemented by clients of the front-end, which
/// formats and prints fully processed diagnostics.
class DiagnosticConsumer {
protected:
@@ -1401,14 +1491,13 @@ protected:
public:
DiagnosticConsumer() = default;
-
virtual ~DiagnosticConsumer();
unsigned getNumErrors() const { return NumErrors; }
unsigned getNumWarnings() const { return NumWarnings; }
virtual void clear() { NumWarnings = NumErrors = 0; }
- /// \brief Callback to inform the diagnostic client that processing
+ /// Callback to inform the diagnostic client that processing
/// of a source file is beginning.
///
/// Note that diagnostics may be emitted outside the processing of a source
@@ -1422,25 +1511,25 @@ public:
virtual void BeginSourceFile(const LangOptions &LangOpts,
const Preprocessor *PP = nullptr) {}
- /// \brief Callback to inform the diagnostic client that processing
+ /// Callback to inform the diagnostic client that processing
/// of a source file has ended.
///
/// The diagnostic client should assume that any objects made available via
/// BeginSourceFile() are inaccessible.
virtual void EndSourceFile() {}
- /// \brief Callback to inform the diagnostic client that processing of all
+ /// Callback to inform the diagnostic client that processing of all
/// source files has ended.
virtual void finish() {}
- /// \brief Indicates whether the diagnostics handled by this
+ /// Indicates whether the diagnostics handled by this
/// DiagnosticConsumer should be included in the number of diagnostics
/// reported by DiagnosticsEngine.
///
/// The default implementation returns true.
virtual bool IncludeInDiagnosticCounts() const;
- /// \brief Handle this diagnostic, reporting it to the user or
+ /// Handle this diagnostic, reporting it to the user or
/// capturing it to a log as needed.
///
/// The default implementation just keeps track of the total number of
@@ -1449,7 +1538,7 @@ public:
const Diagnostic &Info);
};
-/// \brief A diagnostic client that ignores all diagnostics.
+/// A diagnostic client that ignores all diagnostics.
class IgnoringDiagConsumer : public DiagnosticConsumer {
virtual void anchor();
@@ -1459,7 +1548,7 @@ class IgnoringDiagConsumer : public DiagnosticConsumer {
}
};
-/// \brief Diagnostic consumer that forwards diagnostics along to an
+/// Diagnostic consumer that forwards diagnostics along to an
/// existing, already-initialized diagnostic consumer.
///
class ForwardingDiagnosticConsumer : public DiagnosticConsumer {
@@ -1467,7 +1556,6 @@ class ForwardingDiagnosticConsumer : public DiagnosticConsumer {
public:
ForwardingDiagnosticConsumer(DiagnosticConsumer &Target) : Target(Target) {}
-
~ForwardingDiagnosticConsumer() override;
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
@@ -1485,6 +1573,7 @@ struct TemplateDiffTypes {
unsigned PrintFromType : 1;
unsigned ElideType : 1;
unsigned ShowColors : 1;
+
// The printer sets this variable to true if the template diff was used.
unsigned TemplateDiffUsed : 1;
};
@@ -1493,13 +1582,12 @@ struct TemplateDiffTypes {
/// attribute. The character itself will be not be printed.
const char ToggleHighlight = 127;
-
/// ProcessWarningOptions - Initialize the diagnostic client and process the
/// warning options specified on the command line.
void ProcessWarningOptions(DiagnosticsEngine &Diags,
const DiagnosticOptions &Opts,
bool ReportDiags = true);
-} // end namespace clang
+} // namespace clang
#endif // LLVM_CLANG_BASIC_DIAGNOSTIC_H
diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td
index 52ccf350e651e..2a0f1e6385d37 100644
--- a/include/clang/Basic/Diagnostic.td
+++ b/include/clang/Basic/Diagnostic.td
@@ -39,6 +39,15 @@ def SFINAE_Suppress : SFINAEResponse;
def SFINAE_Report : SFINAEResponse;
def SFINAE_AccessControl : SFINAEResponse;
+// Textual substitutions which may be performed on the text of diagnostics
+class TextSubstitution<string Text> {
+ string Substitution = Text;
+ // TODO: These are only here to allow substitutions to be declared inline with
+ // diagnostics
+ string Component = "";
+ string CategoryName = "";
+}
+
// Diagnostic Categories. These can be applied to groups or individual
// diagnostics to specify a category.
class DiagCategory<string Name> {
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index 215580b2e9b66..4fa1db96cb897 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -273,6 +273,8 @@ def note_odr_objc_synthesize_ivar_here : Note<
"property is synthesized to ivar %0 here">;
// Importing C++ ASTs
+def note_odr_friend : Note<"friend declared here">;
+def note_odr_missing_friend : Note<"no corresponding friend here">;
def err_odr_different_num_template_parameters : Error<
"template parameter lists have a different number of parameters (%0 vs %1)">;
def note_odr_template_parameter_list : Note<
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 82ca27b7345e3..61a73541d0b37 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -94,6 +94,9 @@ def remark_module_lock_failure : Remark<
"could not acquire lock file for module '%0': %1">, InGroup<ModuleBuild>;
def remark_module_lock_timeout : Remark<
"timed out waiting to acquire lock file for module '%0'">, InGroup<ModuleBuild>;
+def err_module_shadowed : Error<"import of shadowed module '%0'">, DefaultFatal;
+def err_module_build_shadowed_submodule : Error<
+ "build a shadowed submodule '%0'">, DefaultFatal;
def err_module_cycle : Error<"cyclic dependency in module '%0': %1">,
DefaultFatal;
def err_module_prebuilt : Error<
@@ -165,6 +168,10 @@ def ext_clang_enable_if : Extension<"'enable_if' is a clang extension">,
InGroup<GccCompat>;
def ext_clang_diagnose_if : Extension<"'diagnose_if' is a clang extension">,
InGroup<GccCompat>;
+def err_too_large_for_fixed_point : Error<
+ "this value is too large for this fixed point type">;
+def err_fixed_point_not_enabled : Error<"compile with "
+ "'-ffixed-point' to enable fixed point types">;
// SEH
def err_seh_expected_handler : Error<
@@ -185,6 +192,7 @@ def note_invalid_subexpr_in_const_expr : Note<
def err_target_unknown_triple : Error<
"unknown target triple '%0', please use -triple or -arch">;
def err_target_unknown_cpu : Error<"unknown target CPU '%0'">;
+def note_valid_options : Note<"valid target CPU values are: %0">;
def err_target_unsupported_cpu_for_micromips : Error<
"micromips is not supported for target CPU '%0'">;
def err_target_unknown_abi : Error<"unknown target ABI '%0'">;
@@ -200,6 +208,10 @@ def err_target_unsupported_execute_only : Error<
"execute only is not supported for the %0 sub-architecture">;
def err_opt_not_valid_with_opt : Error<
"option '%0' cannot be specified with '%1'">;
+def err_opt_not_valid_without_opt : Error<
+ "option '%0' cannot be specified without '%1'">;
+def err_opt_not_valid_on_target : Error<
+ "option '%0' cannot be specified on this target">;
// Source manager
def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal;
@@ -226,6 +238,10 @@ def note_mt_message : Note<"[rewriter] %0">;
def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">;
def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">;
+// OpenCL C++.
+def err_openclcxx_not_supported : Error<
+ "'%0' is not supported in OpenCL C++">;
+
// OpenMP
def err_omp_more_one_clause : Error<
"directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier| with 'source' dependence}2">;
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 41b5e42b44322..a6be0595e1ae9 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -11,6 +11,8 @@ let Component = "Driver" in {
def err_drv_no_such_file : Error<"no such file or directory: '%0'">;
def err_drv_unsupported_opt : Error<"unsupported option '%0'">;
+def err_drv_unsupported_opt_with_suggestion
+ : Error<"unsupported option '%0', did you mean '%1'?">;
def err_drv_unsupported_opt_for_target : Error<
"unsupported option '%0' for target '%1'">;
def err_drv_unsupported_option_argument : Error<
@@ -22,6 +24,10 @@ def err_drv_unknown_stdin_type_clang_cl : Error<
def err_drv_unknown_language : Error<"language not recognized: '%0'">;
def err_drv_invalid_arch_name : Error<
"invalid arch name '%0'">;
+def err_drv_invalid_riscv_arch_name : Error<
+ "invalid arch name '%0', %1">;
+def err_drv_invalid_riscv_ext_arch_name : Error<
+ "invalid arch name '%0', %1 '%2'">;
def err_drv_cuda_bad_gpu_arch : Error<"Unsupported CUDA gpu architecture: %0">;
def err_drv_no_cuda_installation : Error<
"cannot find CUDA installation. Provide its path via --cuda-path, or pass "
@@ -34,7 +40,8 @@ def err_drv_cuda_version_unsupported : Error<
"but installation at %3 is %4. Use --cuda-path to specify a different CUDA "
"install, pass a different GPU arch with --cuda-gpu-arch, or pass "
"--no-cuda-version-check.">;
-def err_drv_cuda_nvptx_host : Error<"unsupported use of NVPTX for host compilation.">;
+def err_drv_cuda_host_arch : Error<"unsupported architecture '%0' for host compilation.">;
+def err_drv_mix_cuda_hip : Error<"Mixed Cuda and HIP compilation is not supported.">;
def err_drv_invalid_thread_model_for_target : Error<
"invalid thread model '%0' in '%1' for this target">;
def err_drv_invalid_linker_name : Error<
@@ -112,6 +119,18 @@ def err_drv_invalid_argument_to_fdebug_prefix_map : Error<
"invalid argument '%0' to -fdebug-prefix-map">;
def err_drv_malformed_sanitizer_blacklist : Error<
"malformed sanitizer blacklist: '%0'">;
+def err_drv_duplicate_config : Error<
+ "no more than one option '--config' is allowed">;
+def err_drv_config_file_not_exist : Error<
+ "configuration file '%0' does not exist">;
+def err_drv_config_file_not_found : Error<
+ "configuration file '%0' cannot be found">;
+def note_drv_config_file_searched_in : Note<
+ "was searched for in the directory: %0">;
+def err_drv_cannot_read_config_file : Error<
+ "cannot read configuration file '%0'">;
+def err_drv_nested_config_file: Error<
+ "option '--config' is not allowed inside configuration file">;
def err_target_unsupported_arch
: Error<"the target architecture '%0' is not supported by the target '%1'">;
@@ -123,9 +142,14 @@ def err_arch_unsupported_isa
def err_drv_I_dash_not_supported : Error<
"'%0' not supported, please use -iquote instead">;
def err_drv_unknown_argument : Error<"unknown argument: '%0'">;
+def err_drv_unknown_argument_with_suggestion
+ : Error<"unknown argument '%0', did you mean '%1'?">;
def warn_drv_unknown_argument_clang_cl : Warning<
"unknown argument ignored in clang-cl: '%0'">,
InGroup<UnknownArgument>;
+def warn_drv_unknown_argument_clang_cl_with_suggestion : Warning<
+ "unknown argument ignored in clang-cl '%0' (did you mean '%1'?)">,
+ InGroup<UnknownArgument>;
def warn_drv_ycyu_no_arg_clang_cl : Warning<
"support for '%0' without a filename not implemented yet; flag ignored">,
@@ -169,6 +193,8 @@ def err_drv_mg_requires_m_or_mm : Error<
"option '-MG' requires '-M' or '-MM'">;
def err_drv_unknown_objc_runtime : Error<
"unknown or ill-formed Objective-C runtime '%0'">;
+def err_drv_gnustep_objc_runtime_incompatible_binary : Error<
+ "GNUstep Objective-C runtime version %0 incompatible with target binary format">;
def err_drv_emit_llvm_link : Error<
"-emit-llvm cannot be used when linking">;
def err_drv_optimization_remark_pattern : Error<
@@ -184,6 +210,9 @@ def err_drv_expecting_fopenmp_with_fopenmp_targets : Error<
def warn_drv_omp_offload_target_duplicate : Warning<
"The OpenMP offloading target '%0' is similar to target '%1' already specified - will be ignored.">,
InGroup<OpenMPTarget>;
+def warn_drv_omp_offload_target_missingbcruntime : Warning<
+ "No library '%0' found in the default clang lib directory or in LIBRARY_PATH. Expect degraded performance due to no inlining of runtime functions on target devices.">,
+ InGroup<OpenMPTarget>;
def err_drv_bitcode_unsupported_on_toolchain : Error<
"-fembed-bitcode is not supported on versions of iOS prior to 6.0">;
@@ -239,15 +268,12 @@ def warn_incompatible_sysroot : Warning<"using sysroot for '%0' but targeting '%
InGroup<DiagGroup<"incompatible-sysroot">>;
def warn_debug_compression_unavailable : Warning<"cannot compress debug sections (zlib not installed)">,
InGroup<DiagGroup<"debug-compression-unavailable">>;
-def warn_drv_enabling_rtti_with_exceptions : Warning<
- "implicitly enabling rtti for exception handling">,
- InGroup<DiagGroup<"rtti-for-exceptions">>;
def warn_drv_disabling_vptr_no_rtti_default : Warning<
"implicitly disabling vptr sanitizer because rtti wasn't enabled">,
InGroup<AutoDisableVptrSanitizer>;
def warn_drv_object_size_disabled_O0 : Warning<
"the object size sanitizer has no effect at -O0, but is explicitly enabled: %0">,
- InGroup<InvalidCommandLineArgument>;
+ InGroup<InvalidCommandLineArgument>, DefaultWarnNoWerror;
def note_drv_command_failed_diag_msg : Note<
"diagnostic msg: %0">;
@@ -266,6 +292,9 @@ def err_analyzer_config_multiple_values : Error<
def err_drv_invalid_hvx_length : Error<
"-mhvx-length is not supported without a -mhvx/-mhvx= flag">;
+def warn_drv_vectorize_needs_hvx : Warning<
+ "auto-vectorization requires HVX, use -mhvx to enable it">,
+ InGroup<OptionIgnored>;
def err_drv_modules_validate_once_requires_timestamp : Error<
"option '-fmodules-validate-once-per-build-session' requires "
@@ -310,10 +339,16 @@ def warn_drv_unsupported_longcalls : Warning<
"ignoring '-mlong-calls' option as it is not currently supported with "
"%select{|the implicit usage of }0-mabicalls">,
InGroup<OptionIgnored>;
-def warn_drv_unsupported_abicalls : Warning<
- "ignoring '-mabicalls' option as it cannot be used with "
- "non position-independent code and the N64 ABI">,
+def warn_drv_unsupported_pic_with_mabicalls : Warning<
+ "ignoring '%0' option as it cannot be used with "
+ "%select{implicit usage of|}1 -mabicalls and the N64 ABI">,
InGroup<OptionIgnored>;
+def err_drv_unsupported_noabicalls_pic : Error<
+ "position-independent code requires ‘-mabicalls’">;
+def err_drv_unsupported_indirect_jump_opt : Error<
+ "'-mindirect-jump=%0' is unsupported with the '%1' architecture">;
+def err_drv_unknown_indirect_jump_opt : Error<
+ "unknown '-mindirect-jump=' option '%0'">;
def warn_drv_unable_to_find_directory_expected : Warning<
"unable to find %0 directory, expected to be in '%1'">,
@@ -342,4 +377,16 @@ def warn_drv_fine_grained_bitfield_accesses_ignored : Warning<
def note_drv_verify_prefix_spelling : Note<
"-verify prefixes must start with a letter and contain only alphanumeric"
" characters, hyphens, and underscores">;
+
+def warn_drv_experimental_isel_incomplete : Warning<
+ "-fexperimental-isel support for the '%0' architecture is incomplete">,
+ InGroup<ExperimentalISel>;
+
+def warn_drv_experimental_isel_incomplete_opt : Warning<
+ "-fexperimental-isel support is incomplete for this architecture at the current optimization level">,
+ InGroup<ExperimentalISel>;
+
+def warn_drv_moutline_unsupported_opt : Warning<
+ "The '%0' architecture does not support -moutline; flag ignored">,
+ InGroup<OptionIgnored>;
}
diff --git a/include/clang/Basic/DiagnosticError.h b/include/clang/Basic/DiagnosticError.h
index 6b4b073736a8d..3f7be46c9505e 100644
--- a/include/clang/Basic/DiagnosticError.h
+++ b/include/clang/Basic/DiagnosticError.h
@@ -15,7 +15,7 @@
namespace clang {
-/// \brief Carries a Clang diagnostic in an llvm::Error.
+/// Carries a Clang diagnostic in an llvm::Error.
///
/// Users should emit the stored diagnostic using the DiagnosticsEngine.
class DiagnosticError : public llvm::ErrorInfo<DiagnosticError> {
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index b25181f256586..6add448871fe5 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -118,6 +118,8 @@ def err_fe_invalid_alignment : Error<
"invalid value '%1' in '%0'; alignment must be a power of 2">;
def err_fe_invalid_wchar_type
: Error<"invalid wchar_t type '%0'; must be one of 'char', 'short', 'int'">;
+def err_fe_invalid_exception_model
+ : Error<"invalid exception model '%0' for target '%1'">;
def warn_fe_serialized_diag_merge_failure : Warning<
"unable to merge a subprocess's serialized diagnostics">,
@@ -234,4 +236,9 @@ def err_invalid_vfs_overlay : Error<
def warn_option_invalid_ocl_version : Warning<
"OpenCL version %0 does not support the option '%1'">, InGroup<Deprecated>;
+
+def warn_stdlibcxx_not_found : Warning<
+ "include path for stdlibc++ headers not found; pass '-std=libc++' on the "
+ "command line to use the libc++ standard library instead">,
+ InGroup<DiagGroup<"stdlibcxx-not-found">>;
}
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index c23183c81ac8b..7087db7f0fb89 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -31,6 +31,10 @@ def AutoDisableVptrSanitizer : DiagGroup<"auto-disable-vptr-sanitizer">;
def Availability : DiagGroup<"availability">;
def Section : DiagGroup<"section">;
def AutoImport : DiagGroup<"auto-import">;
+def FrameworkHdrQuotedInclude : DiagGroup<"quoted-include-in-framework-header">;
+def FrameworkIncludePrivateFromPublic :
+ DiagGroup<"framework-include-private-from-public">;
+def FrameworkHdrAtImport : DiagGroup<"atimport-in-framework-header">;
def CXX14BinaryLiteral : DiagGroup<"c++14-binary-literal">;
def CXXPre14CompatBinaryLiteral : DiagGroup<"c++98-c++11-compat-binary-literal">;
def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">;
@@ -116,6 +120,7 @@ def DeprecatedDynamicExceptionSpec
def DeprecatedImplementations :DiagGroup<"deprecated-implementations">;
def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">;
def DeprecatedRegister : DiagGroup<"deprecated-register">;
+def DeprecatedThisCapture : DiagGroup<"deprecated-this-capture">;
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
[CXX11CompatDeprecatedWritableStr]>;
// FIXME: Why is DeprecatedImplementations not in this group?
@@ -124,6 +129,7 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAttributes,
DeprecatedDynamicExceptionSpec,
DeprecatedIncrementBool,
DeprecatedRegister,
+ DeprecatedThisCapture,
DeprecatedWritableStr]>,
DiagCategory<"Deprecations">;
@@ -151,8 +157,10 @@ def Exceptions : DiagGroup<"exceptions">;
def GNUEmptyInitializer : DiagGroup<"gnu-empty-initializer">;
def GNUEmptyStruct : DiagGroup<"gnu-empty-struct">;
def ExtraTokens : DiagGroup<"extra-tokens">;
+def CXX98CompatExtraSemi : DiagGroup<"c++98-compat-extra-semi">;
def CXX11ExtraSemi : DiagGroup<"c++11-extra-semi">;
-def ExtraSemi : DiagGroup<"extra-semi", [CXX11ExtraSemi]>;
+def ExtraSemi : DiagGroup<"extra-semi", [CXX98CompatExtraSemi,
+ CXX11ExtraSemi]>;
def GNUFlexibleArrayInitializer : DiagGroup<"gnu-flexible-array-initializer">;
def GNUFlexibleArrayUnionMember : DiagGroup<"gnu-flexible-array-union-member">;
@@ -196,6 +204,7 @@ def CXX98Compat : DiagGroup<"c++98-compat",
def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
[CXX98Compat,
CXX98CompatBindToTemporaryCopy,
+ CXX98CompatExtraSemi,
CXXPre14CompatPedantic,
CXXPre17CompatPedantic,
CXXPre2aCompatPedantic]>;
@@ -263,6 +272,11 @@ def ShiftOpParentheses: DiagGroup<"shift-op-parentheses">;
def OverloadedShiftOpParentheses: DiagGroup<"overloaded-shift-op-parentheses">;
def DanglingElse: DiagGroup<"dangling-else">;
def DanglingField : DiagGroup<"dangling-field">;
+def DanglingInitializerList : DiagGroup<"dangling-initializer-list">;
+def ReturnStackAddress : DiagGroup<"return-stack-address">;
+def Dangling : DiagGroup<"dangling", [DanglingField,
+ DanglingInitializerList,
+ ReturnStackAddress]>;
def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
def ExpansionToDefined : DiagGroup<"expansion-to-defined">;
def FlagEnum : DiagGroup<"flag-enum">;
@@ -282,6 +296,8 @@ def IncompatiblePointerTypes
[IncompatiblePointerTypesDiscardsQualifiers,
IncompatibleFunctionPointerTypes]>;
def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">;
+def IncompleteFrameworkModuleDeclaration
+ : DiagGroup<"incomplete-framework-module-declaration">;
def NonModularIncludeInFrameworkModule
: DiagGroup<"non-modular-include-in-framework-module">;
def NonModularIncludeInModule : DiagGroup<"non-modular-include-in-module",
@@ -380,7 +396,11 @@ def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
def Packed : DiagGroup<"packed">;
def Padded : DiagGroup<"padded">;
+
def PessimizingMove : DiagGroup<"pessimizing-move">;
+def ReturnStdMoveInCXX11 : DiagGroup<"return-std-move-in-c++11">;
+def ReturnStdMove : DiagGroup<"return-std-move">;
+
def PointerArith : DiagGroup<"pointer-arith">;
def PoundWarning : DiagGroup<"#warnings">;
def PoundPragmaMessage : DiagGroup<"#pragma-messages">,
@@ -391,13 +411,13 @@ def RedeclaredClassMember : DiagGroup<"redeclared-class-member">;
def GNURedeclaredEnum : DiagGroup<"gnu-redeclared-enum">;
def RedundantMove : DiagGroup<"redundant-move">;
def Register : DiagGroup<"register", [DeprecatedRegister]>;
-def ReturnStackAddress : DiagGroup<"return-stack-address">;
def ReturnTypeCLinkage : DiagGroup<"return-type-c-linkage">;
def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>;
def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy",
[CXX98CompatBindToTemporaryCopy]>;
def SelfAssignmentField : DiagGroup<"self-assign-field">;
-def SelfAssignment : DiagGroup<"self-assign", [SelfAssignmentField]>;
+def SelfAssignmentOverloaded : DiagGroup<"self-assign-overloaded">;
+def SelfAssignment : DiagGroup<"self-assign", [SelfAssignmentOverloaded, SelfAssignmentField]>;
def SelfMove : DiagGroup<"self-move">;
def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
def Sentinel : DiagGroup<"sentinel">;
@@ -426,6 +446,13 @@ def : DiagGroup<"synth">;
def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">;
def SizeofArrayDecay : DiagGroup<"sizeof-array-decay">;
def SizeofPointerMemaccess : DiagGroup<"sizeof-pointer-memaccess">;
+def MemsetTransposedArgs : DiagGroup<"memset-transposed-args">;
+def DynamicClassMemaccess : DiagGroup<"dynamic-class-memaccess">;
+def NonTrivialMemaccess : DiagGroup<"nontrivial-memaccess">;
+def SuspiciousBzero : DiagGroup<"suspicious-bzero">;
+def SuspiciousMemaccess : DiagGroup<"suspicious-memaccess",
+ [SizeofPointerMemaccess, DynamicClassMemaccess,
+ NonTrivialMemaccess, MemsetTransposedArgs, SuspiciousBzero]>;
def StaticInInline : DiagGroup<"static-in-inline">;
def StaticLocalInInline : DiagGroup<"static-local-in-inline">;
def GNUStaticFloatInit : DiagGroup<"gnu-static-float-init">;
@@ -435,13 +462,16 @@ def StringCompare : DiagGroup<"string-compare">;
def StringPlusInt : DiagGroup<"string-plus-int">;
def StringPlusChar : DiagGroup<"string-plus-char">;
def StrncatSize : DiagGroup<"strncat-size">;
+def TautologicalTypeLimitCompare : DiagGroup<"tautological-type-limit-compare">;
def TautologicalUnsignedZeroCompare : DiagGroup<"tautological-unsigned-zero-compare">;
def TautologicalUnsignedEnumZeroCompare : DiagGroup<"tautological-unsigned-enum-zero-compare">;
+def TautologicalInRangeCompare : DiagGroup<"tautological-constant-in-range-compare",
+ [TautologicalTypeLimitCompare,
+ TautologicalUnsignedZeroCompare,
+ TautologicalUnsignedEnumZeroCompare]>;
def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
def TautologicalConstantCompare : DiagGroup<"tautological-constant-compare",
- [TautologicalUnsignedZeroCompare,
- TautologicalUnsignedEnumZeroCompare,
- TautologicalOutOfRangeCompare]>;
+ [TautologicalOutOfRangeCompare]>;
def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">;
def TautologicalUndefinedCompare : DiagGroup<"tautological-undefined-compare">;
@@ -509,8 +539,13 @@ def UninitializedStaticSelfInit : DiagGroup<"static-self-init">;
def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes,
UninitializedStaticSelfInit]>;
def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">;
+// #pragma optimize is often used to avoid to work around MSVC codegen bugs or
+// to disable inlining. It's not completely clear what alternative to suggest
+// (#pragma clang optimize, noinline) so suggest nothing for now.
+def IgnoredPragmaOptimize : DiagGroup<"ignored-pragma-optimize">;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
-def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>;
+def IgnoredPragmas : DiagGroup<"ignored-pragmas",
+ [IgnoredPragmaIntrinsic, IgnoredPragmaOptimize]>;
def PragmaClangAttribute : DiagGroup<"pragma-clang-attribute">;
def PragmaPackSuspiciousInclude : DiagGroup<"pragma-pack-suspicious-include">;
def PragmaPack : DiagGroup<"pragma-pack", [PragmaPackSuspiciousInclude]>;
@@ -712,7 +747,12 @@ def IntToVoidPointerCast : DiagGroup<"int-to-void-pointer-cast">;
def IntToPointerCast : DiagGroup<"int-to-pointer-cast",
[IntToVoidPointerCast]>;
-def Move : DiagGroup<"move", [PessimizingMove, RedundantMove, SelfMove]>;
+def Move : DiagGroup<"move", [
+ PessimizingMove,
+ RedundantMove,
+ ReturnStdMove,
+ SelfMove
+ ]>;
def Extra : DiagGroup<"extra", [
MissingFieldInitializers,
@@ -982,3 +1022,10 @@ def UnknownArgument : DiagGroup<"unknown-argument">;
// A warning group for warnings about code that clang accepts when
// compiling OpenCL C/C++ but which is not compatible with the SPIR spec.
def SpirCompat : DiagGroup<"spir-compat">;
+
+// Warning for the experimental-isel options.
+def ExperimentalISel : DiagGroup<"experimental-isel">;
+
+// A warning group specifically for warnings related to function
+// multiversioning.
+def FunctionMultiVersioning : DiagGroup<"function-multiversion">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index b4ea85ba853cc..b610af953fba1 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the Diagnostic IDs-related interfaces.
+/// Defines the Diagnostic IDs-related interfaces.
///
//===----------------------------------------------------------------------===//
@@ -60,7 +60,7 @@ namespace clang {
class CustomDiagInfo;
- /// \brief All of the diagnostics that can be emitted by the frontend.
+ /// All of the diagnostics that can be emitted by the frontend.
typedef unsigned kind;
// Get typedefs for common diagnostics.
@@ -158,25 +158,25 @@ public:
}
};
-/// \brief Used for handling and querying diagnostic IDs.
+/// Used for handling and querying diagnostic IDs.
///
/// Can be used and shared by multiple Diagnostics for multiple translation units.
class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
public:
- /// \brief The level of the diagnostic, after it has been through mapping.
+ /// The level of the diagnostic, after it has been through mapping.
enum Level {
Ignored, Note, Remark, Warning, Error, Fatal
};
private:
- /// \brief Information for uniquing and looking up custom diags.
+ /// Information for uniquing and looking up custom diags.
diag::CustomDiagInfo *CustomDiagInfo;
public:
DiagnosticIDs();
~DiagnosticIDs();
- /// \brief Return an ID for a diagnostic with the specified format string and
+ /// Return an ID for a diagnostic with the specified format string and
/// level.
///
/// If this is the first request for this diagnostic, it is registered and
@@ -191,31 +191,31 @@ public:
// Diagnostic classification and reporting interfaces.
//
- /// \brief Given a diagnostic ID, return a description of the issue.
+ /// Given a diagnostic ID, return a description of the issue.
StringRef getDescription(unsigned DiagID) const;
- /// \brief Return true if the unmapped diagnostic levelof the specified
+ /// Return true if the unmapped diagnostic levelof the specified
/// diagnostic ID is a Warning or Extension.
///
/// This only works on builtin diagnostics, not custom ones, and is not
/// legal to call on NOTEs.
static bool isBuiltinWarningOrExtension(unsigned DiagID);
- /// \brief Return true if the specified diagnostic is mapped to errors by
+ /// Return true if the specified diagnostic is mapped to errors by
/// default.
static bool isDefaultMappingAsError(unsigned DiagID);
- /// \brief Determine whether the given built-in diagnostic ID is a Note.
+ /// Determine whether the given built-in diagnostic ID is a Note.
static bool isBuiltinNote(unsigned DiagID);
- /// \brief Determine whether the given built-in diagnostic ID is for an
+ /// Determine whether the given built-in diagnostic ID is for an
/// extension of some sort.
static bool isBuiltinExtensionDiag(unsigned DiagID) {
bool ignored;
return isBuiltinExtensionDiag(DiagID, ignored);
}
- /// \brief Determine whether the given built-in diagnostic ID is for an
+ /// Determine whether the given built-in diagnostic ID is for an
/// extension of some sort, and whether it is enabled by default.
///
/// This also returns EnabledByDefault, which is set to indicate whether the
@@ -225,53 +225,53 @@ public:
static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
- /// \brief Return the lowest-level warning option that enables the specified
+ /// Return the lowest-level warning option that enables the specified
/// diagnostic.
///
/// If there is no -Wfoo flag that controls the diagnostic, this returns null.
static StringRef getWarningOptionForDiag(unsigned DiagID);
- /// \brief Return the category number that a specified \p DiagID belongs to,
+ /// Return the category number that a specified \p DiagID belongs to,
/// or 0 if no category.
static unsigned getCategoryNumberForDiag(unsigned DiagID);
- /// \brief Return the number of diagnostic categories.
+ /// Return the number of diagnostic categories.
static unsigned getNumberOfCategories();
- /// \brief Given a category ID, return the name of the category.
+ /// Given a category ID, return the name of the category.
static StringRef getCategoryNameFromID(unsigned CategoryID);
- /// \brief Return true if a given diagnostic falls into an ARC diagnostic
+ /// Return true if a given diagnostic falls into an ARC diagnostic
/// category.
static bool isARCDiagnostic(unsigned DiagID);
- /// \brief Enumeration describing how the emission of a diagnostic should
+ /// Enumeration describing how the emission of a diagnostic should
/// be treated when it occurs during C++ template argument deduction.
enum SFINAEResponse {
- /// \brief The diagnostic should not be reported, but it should cause
+ /// The diagnostic should not be reported, but it should cause
/// template argument deduction to fail.
///
/// The vast majority of errors that occur during template argument
/// deduction fall into this category.
SFINAE_SubstitutionFailure,
- /// \brief The diagnostic should be suppressed entirely.
+ /// The diagnostic should be suppressed entirely.
///
/// Warnings generally fall into this category.
SFINAE_Suppress,
- /// \brief The diagnostic should be reported.
+ /// The diagnostic should be reported.
///
/// The diagnostic should be reported. Various fatal errors (e.g.,
/// template instantiation depth exceeded) fall into this category.
SFINAE_Report,
- /// \brief The diagnostic is an access-control diagnostic, which will be
+ /// The diagnostic is an access-control diagnostic, which will be
/// substitution failures in some contexts and reported in others.
SFINAE_AccessControl
};
- /// \brief Determines whether the given built-in diagnostic ID is
+ /// Determines whether the given built-in diagnostic ID is
/// for an error that is suppressed if it occurs during C++ template
/// argument deduction.
///
@@ -281,30 +281,30 @@ public:
/// are not SFINAE errors.
static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
- /// \brief Get the string of all diagnostic flags.
+ /// Get the string of all diagnostic flags.
///
/// \returns A list of all diagnostics flags as they would be written in a
/// command line invocation including their `no-` variants. For example:
/// `{"-Wempty-body", "-Wno-empty-body", ...}`
static std::vector<std::string> getDiagnosticFlags();
- /// \brief Get the set of all diagnostic IDs in the group with the given name.
+ /// Get the set of all diagnostic IDs in the group with the given name.
///
/// \param[out] Diags - On return, the diagnostics in the group.
/// \returns \c true if the given group is unknown, \c false otherwise.
bool getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group,
SmallVectorImpl<diag::kind> &Diags) const;
- /// \brief Get the set of all diagnostic IDs.
+ /// Get the set of all diagnostic IDs.
static void getAllDiagnostics(diag::Flavor Flavor,
std::vector<diag::kind> &Diags);
- /// \brief Get the diagnostic option with the closest edit distance to the
+ /// Get the diagnostic option with the closest edit distance to the
/// given group name.
static StringRef getNearestOption(diag::Flavor Flavor, StringRef Group);
private:
- /// \brief Classify the specified diagnostic ID into a Level, consumable by
+ /// Classify the specified diagnostic ID into a Level, consumable by
/// the DiagnosticClient.
///
/// The classification is based on the way the client configured the
@@ -320,17 +320,17 @@ private:
getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
const DiagnosticsEngine &Diag) const LLVM_READONLY;
- /// \brief Used to report a diagnostic that is finally fully formed.
+ /// Used to report a diagnostic that is finally fully formed.
///
/// \returns \c true if the diagnostic was emitted, \c false if it was
/// suppressed.
bool ProcessDiag(DiagnosticsEngine &Diag) const;
- /// \brief Used to emit a diagnostic that is finally fully formed,
+ /// Used to emit a diagnostic that is finally fully formed,
/// ignoring suppression.
void EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const;
- /// \brief Whether the diagnostic may leave the AST in a state where some
+ /// Whether the diagnostic may leave the AST in a state where some
/// invariants can break.
bool isUnrecoverable(unsigned DiagID) const;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index c391470cb1c89..b5b5e8f654bca 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -404,6 +404,14 @@ def err_pp_invalid_directive : Error<"invalid preprocessing directive">;
def err_pp_directive_required : Error<
"%0 must be used within a preprocessing directive">;
def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal;
+def err_pp_through_header_not_found : Error<
+ "'%0' required for precompiled header not found">, DefaultFatal;
+def err_pp_through_header_not_seen : Error<
+ "#include of '%0' not seen while attempting to "
+ "%select{create|use}1 precompiled header">, DefaultFatal;
+def warn_pp_macro_def_mismatch_with_pch : Warning<
+ "definition of macro %0 does not match definition in precompiled header">,
+ InGroup<ClangClPch>;
def err_pp_file_not_found_not_fatal : Error<
"'%0' file not found with <angled> include; use \"quotes\" instead">;
def err_pp_error_opening_file : Error<
@@ -505,17 +513,12 @@ def warn_pragma_message : Warning<"%0">,
def err_pragma_message : Error<"%0">;
def warn_pragma_ignored : Warning<"unknown pragma ignored">,
InGroup<UnknownPragmas>, DefaultIgnore;
-def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
- InGroup<UnknownPragmas>;
def ext_on_off_switch_syntax :
ExtWarn<"expected 'ON' or 'OFF' or 'DEFAULT' in pragma">,
InGroup<UnknownPragmas>;
def ext_pragma_syntax_eod :
ExtWarn<"expected end of directive in pragma">,
InGroup<UnknownPragmas>;
-def warn_stdc_fenv_access_not_supported :
- Warning<"pragma STDC FENV_ACCESS ON is not supported, ignoring pragma">,
- InGroup<UnknownPragmas>;
def warn_pragma_diagnostic_invalid :
ExtWarn<"pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal',"
" 'push', or 'pop'">,
@@ -699,6 +702,11 @@ def warn_mmap_mismatched_private_module_name : Warning<
InGroup<PrivateModule>;
def note_mmap_rename_top_level_private_module : Note<
"rename '%0' to ensure it can be found by name">;
+def warn_mmap_incomplete_framework_module_declaration : Warning<
+ "skipping '%0' because module declaration of '%1' lacks the 'framework' qualifier">,
+ InGroup<IncompleteFrameworkModuleDeclaration>;
+def note_mmap_add_framework_keyword : Note<
+ "use 'framework module' to declare module '%0'">;
def err_mmap_duplicate_header_attribute : Error<
"header attribute '%0' specified multiple times">;
@@ -714,6 +722,14 @@ def warn_mmap_redundant_export_as : Warning<
def err_mmap_submodule_export_as : Error<
"only top-level modules can be re-exported as public">;
+def warn_quoted_include_in_framework_header : Warning<
+ "double-quoted include \"%0\" in framework header, "
+ "expected angle-bracketed instead"
+ >, InGroup<FrameworkHdrQuotedInclude>, DefaultIgnore;
+def warn_framework_include_private_from_public : Warning<
+ "public framework header includes private framework header '%0'"
+ >, InGroup<FrameworkIncludePrivateFromPublic>;
+
def warn_auto_module_import : Warning<
"treating #%select{include|import|include_next|__include_macros}0 as an "
"import of module '%1'">, InGroup<AutoImport>, DefaultIgnore;
diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h
index 3844eb63f0eaf..391e252eaddda 100644
--- a/include/clang/Basic/DiagnosticOptions.h
+++ b/include/clang/Basic/DiagnosticOptions.h
@@ -1,4 +1,4 @@
-//===--- DiagnosticOptions.h ------------------------------------*- C++ -*-===//
+//===- DiagnosticOptions.h --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,14 +18,17 @@
namespace clang {
-/// \brief Specifies which overload candidates to display when overload
+/// Specifies which overload candidates to display when overload
/// resolution fails.
enum OverloadsShown : unsigned {
- Ovl_All, ///< Show all overloads.
- Ovl_Best ///< Show just the "best" overload candidates.
+ /// Show all overloads.
+ Ovl_All,
+
+ /// Show just the "best" overload candidates.
+ Ovl_Best
};
-/// \brief A bitmask representing the diagnostic levels used by
+/// A bitmask representing the diagnostic levels used by
/// VerifyDiagnosticConsumer.
enum class DiagnosticLevelMask : unsigned {
None = 0,
@@ -57,7 +60,7 @@ inline DiagnosticLevelMask operator&(DiagnosticLevelMask LHS,
raw_ostream& operator<<(raw_ostream& Out, DiagnosticLevelMask M);
-/// \brief Options for controlling the compiler diagnostics engine.
+/// Options for controlling the compiler diagnostics engine.
class DiagnosticOptions : public RefCountedBase<DiagnosticOptions>{
public:
enum TextDiagnosticFormat { Clang, MSVC, Vi };
@@ -86,10 +89,10 @@ protected:
#include "clang/Basic/DiagnosticOptions.def"
public:
- /// \brief The file to log diagnostic output to.
+ /// The file to log diagnostic output to.
std::string DiagnosticLogFile;
- /// \brief The file to serialize diagnostics to (non-appending).
+ /// The file to serialize diagnostics to (non-appending).
std::string DiagnosticSerializationFile;
/// The list of -W... options used to alter the diagnostic mappings, with the
@@ -119,8 +122,8 @@ public:
}
};
-typedef DiagnosticOptions::TextDiagnosticFormat TextDiagnosticFormat;
+using TextDiagnosticFormat = DiagnosticOptions::TextDiagnosticFormat;
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICOPTIONS_H
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 7936cdd96f80b..dd4c81922592f 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -39,7 +39,7 @@ def ext_empty_translation_unit : Extension<
InGroup<DiagGroup<"empty-translation-unit">>;
def warn_cxx98_compat_top_level_semi : Warning<
"extra ';' outside of a function is incompatible with C++98">,
- InGroup<CXX98CompatPedantic>, DefaultIgnore;
+ InGroup<CXX98CompatExtraSemi>, DefaultIgnore;
def ext_extra_semi : Extension<
"extra ';' %select{"
"outside of a function|"
@@ -173,6 +173,9 @@ def warn_attribute_on_function_definition : Warning<
def warn_gcc_attribute_location : Warning<
"GCC does not allow an attribute in this position on a function declaration">,
InGroup<GccCompat>;
+def warn_gcc_variable_decl_in_for_loop : Warning<
+ "GCC does not allow variable declarations in for loop initializers before "
+ "C99">, InGroup<GccCompat>;
def warn_attribute_no_decl : Warning<
"attribute %0 ignored, because it is not attached to a declaration">,
InGroup<IgnoredAttributes>;
@@ -248,6 +251,11 @@ def err_unexpected_at : Error<"unexpected '@' in program">;
def err_atimport : Error<
"use of '@import' when modules are disabled">;
+def warn_atimport_in_framework_header : Warning<
+ "use of '@import' in framework header is discouraged, "
+ "including this header requires -fmodules">,
+ InGroup<FrameworkHdrAtImport>;
+
def err_invalid_reference_qualifier_application : Error<
"'%0' qualifier may not be applied to a reference">;
def err_illegal_decl_reference_to_reference : Error<
@@ -575,7 +583,7 @@ def err_cxx11_attribute_forbids_arguments : Error<
def err_attribute_requires_arguments : Error<
"parentheses must be omitted if %0 attribute's argument list is empty">;
def err_cxx11_attribute_forbids_ellipsis : Error<
- "attribute '%0' cannot be used as an attribute pack">;
+ "attribute %0 cannot be used as an attribute pack">;
def err_cxx11_attribute_repeated : Error<
"attribute %0 cannot appear multiple times in an attribute specifier">;
def warn_cxx14_compat_using_attribute_ns : Warning<
@@ -633,6 +641,8 @@ def err_template_spec_syntax_non_template : Error<
"<unused>|refers to a variable template|<unused>}1">;
def err_id_after_template_in_nested_name_spec : Error<
"expected template name after 'template' keyword in nested name specifier">;
+def err_unexpected_template_in_unqualified_id : Error<
+ "'template' keyword not permitted here">;
def err_two_right_angle_brackets_need_space : Error<
"a space is required between consecutive right angle brackets (use '> >')">;
def err_right_angle_bracket_equal_needs_space : Error<
@@ -895,6 +905,12 @@ def warn_pragma_expected_rparen : Warning<
"missing ')' after '#pragma %0' - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_expected_identifier : Warning<
"expected identifier in '#pragma %0' - ignored">, InGroup<IgnoredPragmas>;
+def warn_pragma_expected_string : Warning<
+ "expected string literal in '#pragma %0' - ignoring">, InGroup<IgnoredPragmas>;
+def warn_pragma_missing_argument : Warning<
+ "missing argument to '#pragma %0'%select{|; expected %2}1">, InGroup<IgnoredPragmas>;
+def warn_pragma_invalid_argument : Warning<
+ "unexpected argument '%0' to '#pragma %1'%select{|; expected %3}2">, InGroup<IgnoredPragmas>;
// '#pragma clang section' related errors
def err_pragma_expected_clang_section_name : Error<
@@ -923,6 +939,8 @@ def warn_pragma_ms_struct : Warning<
def warn_pragma_extra_tokens_at_eol : Warning<
"extra tokens at end of '#pragma %0' - ignored">,
InGroup<IgnoredPragmas>;
+def warn_pragma_expected_comma : Warning<
+ "expected ',' in '#pragma %0'">, InGroup<IgnoredPragmas>;
def warn_pragma_expected_punc : Warning<
"expected ')' or ',' in '#pragma %0'">, InGroup<IgnoredPragmas>;
def warn_pragma_expected_non_wide_string : Warning<
@@ -960,6 +978,10 @@ def warn_pragma_pack_malformed : Warning<
def warn_pragma_intrinsic_builtin : Warning<
"%0 is not a recognized builtin%select{|; consider including <intrin.h> to access non-builtin intrinsics}1">,
InGroup<IgnoredPragmaIntrinsic>;
+// - #pragma optimize
+def warn_pragma_optimize : Warning<
+ "'#pragma optimize' is not supported">,
+ InGroup<IgnoredPragmaOptimize>;
// - #pragma unused
def warn_pragma_unused_expected_var : Warning<
"expected '#pragma unused' argument to be a variable name">,
@@ -973,6 +995,12 @@ def warn_pragma_init_seg_unsupported_target : Warning<
def err_pragma_fp_contract_scope : Error<
"'#pragma fp_contract' can only appear at file scope or at the start of a "
"compound statement">;
+// - #pragma stdc unknown
+def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
+ InGroup<UnknownPragmas>;
+def warn_stdc_fenv_access_not_supported :
+ Warning<"pragma STDC FENV_ACCESS ON is not supported, ignoring pragma">,
+ InGroup<UnknownPragmas>;
// - #pragma comment
def err_pragma_comment_malformed : Error<
"pragma comment requires parenthesized identifier and optional string">;
@@ -1055,6 +1083,12 @@ def err_opencl_taking_function_address_parser : Error<
def err_opencl_logical_exclusive_or : Error<
"^^ is a reserved operator in OpenCL">;
+// OpenCL C++.
+def err_openclcxx_virtual_function : Error<
+ "virtual functions are not supported in OpenCL C++">;
+def err_openclcxx_reserved : Error<
+ "'%0' is a reserved keyword in OpenCL C++">;
+
// OpenMP support.
def warn_pragma_omp_ignored : Warning<
"unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore;
@@ -1066,7 +1100,7 @@ def warn_pragma_expected_colon_r_paren : Warning<
def err_omp_unknown_directive : Error<
"expected an OpenMP directive">;
def err_omp_unexpected_directive : Error<
- "unexpected OpenMP directive '#pragma omp %0'">;
+ "unexpected OpenMP directive %select{|'#pragma omp %1'}0">;
def err_omp_expected_punc : Error<
"expected ',' or ')' in '%0' %select{clause|directive}1">;
def err_omp_unexpected_clause : Error<
@@ -1156,6 +1190,9 @@ def err_objc_parameterized_implementation : Error<
def err_objc_type_args_after_protocols : Error<
"protocol qualifiers must precede type arguments">;
+
+def note_meant_to_use_typename : Note<
+ "did you mean to use 'typename'?">;
}
let CategoryName = "Coroutines Issue" in {
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 01e819942f686..d0a2bec780527 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -203,6 +203,8 @@ def ext_imaginary_constant : Extension<
def ext_integer_complex : Extension<
"complex integer types are a GNU extension">, InGroup<GNUComplexInteger>;
+def err_invalid_saturation_spec : Error<"'_Sat' specifier is only valid on "
+ "'_Fract' or '_Accum', not '%0'">;
def err_invalid_sign_spec : Error<"'%0' cannot be signed or unsigned">;
def err_invalid_width_spec : Error<
"'%select{|short|long|long long}0 %1' is invalid">;
@@ -272,6 +274,14 @@ def warn_mips_interrupt_attribute : Warning<
"MIPS 'interrupt' attribute only applies to functions that have "
"%select{no parameters|a 'void' return type}0">,
InGroup<IgnoredAttributes>;
+def warn_riscv_repeated_interrupt_attribute : Warning<
+ "repeated RISC-V 'interrupt' attribute">, InGroup<IgnoredAttributes>;
+def note_riscv_repeated_interrupt_attribute : Note<
+ "repeated RISC-V 'interrupt' attribute is here">;
+def warn_riscv_interrupt_attribute : Warning<
+ "RISC-V 'interrupt' attribute only applies to functions that have "
+ "%select{no parameters|a 'void' return type}0">,
+ InGroup<IgnoredAttributes>;
def warn_unused_parameter : Warning<"unused parameter %0">,
InGroup<UnusedParameter>, DefaultIgnore;
def warn_unused_variable : Warning<"unused variable %0">,
@@ -279,7 +289,7 @@ def warn_unused_variable : Warning<"unused variable %0">,
def warn_unused_local_typedef : Warning<
"unused %select{typedef|type alias}0 %1">,
InGroup<UnusedLocalTypedef>, DefaultIgnore;
-def warn_unused_property_backing_ivar :
+def warn_unused_property_backing_ivar :
Warning<"ivar %0 which backs the property is not "
"referenced in this property's accessor">,
InGroup<UnusedPropertyIvar>, DefaultIgnore;
@@ -602,9 +612,12 @@ def warn_redecl_library_builtin : Warning<
"incompatible redeclaration of library function %0">,
InGroup<DiagGroup<"incompatible-library-redeclaration">>;
def err_builtin_definition : Error<"definition of builtin function %0">;
+def err_builtin_redeclare : Error<"cannot redeclare builtin function %0">;
def err_arm_invalid_specialreg : Error<"invalid special register for builtin">;
def err_invalid_cpu_supports : Error<"invalid cpu feature string for builtin">;
def err_invalid_cpu_is : Error<"invalid cpu name for builtin">;
+def err_invalid_cpu_specific_dispatch_value : Error<
+"invalid option '%0' for %select{cpu_specific|cpu_dispatch}1">;
def err_builtin_needs_feature : Error<"%0 needs target feature %1">;
def err_function_needs_feature
: Error<"always_inline function %1 requires target feature '%2', but would "
@@ -612,11 +625,18 @@ def err_function_needs_feature
"'%2'">;
def warn_builtin_unknown : Warning<"use of unknown builtin %0">,
InGroup<ImplicitFunctionDeclare>, DefaultError;
+def warn_cstruct_memaccess : Warning<
+ "%select{destination for|source of|first operand of|second operand of}0 this "
+ "%1 call is a pointer to record %2 that is not trivial to "
+ "%select{primitive-default-initialize|primitive-copy}3">,
+ InGroup<NonTrivialMemaccess>;
+def note_nontrivial_field : Note<
+ "field is non-trivial to %select{copy|default-initialize}0">;
def warn_dyn_class_memaccess : Warning<
"%select{destination for|source of|first operand of|second operand of}0 this "
"%1 call is a pointer to %select{|class containing a }2dynamic class %3; "
"vtable pointer will be %select{overwritten|copied|moved|compared}4">,
- InGroup<DiagGroup<"dynamic-class-memaccess">>;
+ InGroup<DynamicClassMemaccess>;
def note_bad_memaccess_silence : Note<
"explicitly cast the pointer to silence this warning">;
def warn_sizeof_pointer_expr_memaccess : Warning<
@@ -645,7 +665,19 @@ def note_memsize_comparison_paren : Note<
"did you mean to compare the result of %0 instead?">;
def note_memsize_comparison_cast_silence : Note<
"explicitly cast the argument to size_t to silence this warning">;
-
+def warn_suspicious_sizeof_memset : Warning<
+ "%select{'size' argument to memset is '0'|"
+ "setting buffer to a 'sizeof' expression}0"
+ "; did you mean to transpose the last two arguments?">,
+ InGroup<MemsetTransposedArgs>;
+def note_suspicious_sizeof_memset_silence : Note<
+ "%select{parenthesize the third argument|"
+ "cast the second argument to 'int'}0 to silence">;
+def warn_suspicious_bzero_size : Warning<"'size' argument to bzero is '0'">,
+ InGroup<SuspiciousBzero>;
+def note_suspicious_bzero_size_silence : Note<
+ "parenthesize the second argument to silence">;
+
def warn_strncat_large_size : Warning<
"the value of the size argument in 'strncat' is too large, might lead to a "
"buffer overflow">, InGroup<StrncatSize>;
@@ -751,7 +783,7 @@ def note_pragma_pack_pop_instead_reset : Note<
"did you intend to use '#pragma pack (pop)' instead of '#pragma pack()'?">;
// Follow the Microsoft implementation.
def warn_pragma_pack_show : Warning<"value of #pragma pack(show) == %0">;
-def warn_pragma_pack_pop_identifer_and_alignment : Warning<
+def warn_pragma_pack_pop_identifier_and_alignment : Warning<
"specifying both a name and alignment to 'pop' is undefined">;
def warn_pragma_pop_failed : Warning<"#pragma %0(pop, ...) failed: %1">,
InGroup<IgnoredPragmas>;
@@ -759,6 +791,10 @@ def warn_cxx_ms_struct :
Warning<"ms_struct may not produce Microsoft-compatible layouts for classes "
"with base classes or virtual functions">,
DefaultError, InGroup<IncompatibleMSStruct>;
+def warn_npot_ms_struct :
+ Warning<"ms_struct may not produce Microsoft-compatible layouts with fundamental "
+ "data types with sizes that aren't a power of two">,
+ DefaultError, InGroup<IncompatibleMSStruct>;
def err_section_conflict : Error<"%0 causes a section type conflict with %1">;
def err_no_base_classes : Error<"invalid use of '__super', %0 has no base classes">;
def err_invalid_super_scope : Error<"invalid use of '__super', "
@@ -1027,7 +1063,7 @@ def warn_objc_pointer_masking : Warning<
def warn_objc_pointer_masking_performSelector : Warning<warn_objc_pointer_masking.Text>,
InGroup<ObjCPointerIntrospectPerformSelector>;
def warn_objc_property_default_assign_on_object : Warning<
- "default property attribute 'assign' not appropriate for non-GC object">,
+ "default property attribute 'assign' not appropriate for object">,
InGroup<ObjCPropertyNoAttribute>;
def warn_property_attr_mismatch : Warning<
"property attribute in class extension does not match the primary class">,
@@ -1325,7 +1361,7 @@ def err_invalid_member_in_interface : Error<
"nested class }0%1 is not permitted within an interface type">;
def err_invalid_base_in_interface : Error<
"interface type cannot inherit from "
- "%select{'struct|non-public 'interface|'class}0 %1'">;
+ "%select{struct|non-public interface|class}0 %1">;
def err_abstract_type_in_decl : Error<
"%select{return|parameter|variable|field|instance variable|"
@@ -1582,6 +1618,8 @@ def err_not_integral_type_bitfield : Error<
"bit-field %0 has non-integral type %1">;
def err_not_integral_type_anon_bitfield : Error<
"anonymous bit-field has non-integral type %0">;
+def err_anon_bitfield_qualifiers : Error<
+ "anonymous bit-field cannot have qualifiers">;
def err_member_function_initialization : Error<
"initializer on function does not look like a pure-specifier">;
def err_non_virtual_pure : Error<
@@ -1589,24 +1627,35 @@ def err_non_virtual_pure : Error<
def ext_pure_function_definition : ExtWarn<
"function definition with pure-specifier is a Microsoft extension">,
InGroup<MicrosoftPureDefinition>;
-def err_implicit_object_parameter_init : Error<
- "cannot initialize object parameter of type %0 with an expression "
- "of type %1">;
def err_qualified_member_of_unrelated : Error<
"%q0 is not a member of class %1">;
+def err_member_function_call_bad_cvr : Error<
+ "'this' argument to member function %0 has type %1, but function is not marked "
+ "%select{const|restrict|const or restrict|volatile|const or volatile|"
+ "volatile or restrict|const, volatile, or restrict}2">;
+def err_member_function_call_bad_ref : Error<
+ "'this' argument to member function %0 is an %select{lvalue|rvalue}1, "
+ "but function has %select{non-const lvalue|rvalue}2 ref-qualifier">;
+def err_member_function_call_bad_type : Error<
+ "cannot initialize object parameter of type %0 with an expression "
+ "of type %1">;
+
def warn_call_to_pure_virtual_member_function_from_ctor_dtor : Warning<
"call to pure virtual member function %0 has undefined behavior; "
"overrides of %0 in subclasses are not available in the "
"%select{constructor|destructor}1 of %2">;
+def select_special_member_kind : TextSubstitution<
+ "%select{default constructor|copy constructor|move constructor|"
+ "copy assignment operator|move assignment operator|destructor}0">;
+
def note_member_declared_at : Note<"member is declared here">;
def note_ivar_decl : Note<"instance variable is declared here">;
def note_bitfield_decl : Note<"bit-field is declared here">;
def note_implicit_param_decl : Note<"%0 is an implicit parameter">;
def note_member_synthesized_at : Note<
- "in implicit %select{default constructor|copy constructor|move constructor|"
- "copy assignment operator|move assignment operator|destructor}0 for %1 "
+ "in implicit %sub{select_special_member_kind}0 for %1 "
"first required here">;
def err_missing_default_ctor : Error<
"%select{constructor for %1 must explicitly initialize the|"
@@ -1615,16 +1664,14 @@ def err_missing_default_ctor : Error<
"%select{base class|member}2 %3 %select{which|which|of %1}0 "
"does not have a default constructor">;
def note_due_to_dllexported_class : Note<
- "due to '%0' being dllexported%select{|; try compiling in C++11 mode}1">;
+ "due to %0 being dllexported%select{|; try compiling in C++11 mode}1">;
def err_illegal_union_or_anon_struct_member : Error<
"%select{anonymous struct|union}0 member %1 has a non-trivial "
- "%select{constructor|copy constructor|move constructor|copy assignment "
- "operator|move assignment operator|destructor}2">;
+ "%sub{select_special_member_kind}2">;
def warn_cxx98_compat_nontrivial_union_or_anon_struct_member : Warning<
"%select{anonymous struct|union}0 member %1 with a non-trivial "
- "%select{constructor|copy constructor|move constructor|copy assignment "
- "operator|move assignment operator|destructor}2 is incompatible with C++98">,
+ "%sub{select_special_member_kind}2 is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def note_nontrivial_virtual_dtor : Note<
@@ -1643,8 +1690,7 @@ def note_nontrivial_no_copy : Note<
"%select{base class|field|an object}0 of type %3">;
def note_nontrivial_user_provided : Note<
"because %select{base class of |field of |}0type %1 has a user-provided "
- "%select{default constructor|copy constructor|move constructor|"
- "copy assignment operator|move assignment operator|destructor}2">;
+ "%sub{select_special_member_kind}2">;
def note_nontrivial_in_class_init : Note<
"because field %0 has an initializer">;
def note_nontrivial_param_type : Note<
@@ -1711,9 +1757,7 @@ def err_covariant_return_type_class_type_more_qualified : Error<
// C++ implicit special member functions
def note_in_declaration_of_implicit_special_member : Note<
- "while declaring the implicit "
- "%select{default constructor|copy constructor|move constructor|"
- "copy assignment operator|move assignment operator|destructor}1"
+ "while declaring the implicit %sub{select_special_member_kind}1"
" for %0">;
// C++ constructors
@@ -1768,7 +1812,8 @@ def err_destructor_template : Error<
// C++ initialization
def err_init_conversion_failed : Error<
- "cannot initialize %select{a variable|a parameter|return object|an "
+ "cannot initialize %select{a variable|a parameter|return object|"
+ "statement expression result|an "
"exception object|a member subobject|an array element|a new value|a value|a "
"base class|a constructor delegation|a vector element|a block element|a "
"block element|a complex element|a lambda capture|a compound literal "
@@ -1808,17 +1853,9 @@ def err_reference_bind_failed : Error<
"type $|could not bind to %select{rvalue|lvalue}1 of incompatible type}0,2">;
def err_reference_bind_init_list : Error<
"reference to type %0 cannot bind to an initializer list">;
-def warn_temporary_array_to_pointer_decay : Warning<
- "pointer is initialized by a temporary array, which will be destroyed at the "
- "end of the full-expression">,
- InGroup<DiagGroup<"address-of-array-temporary">>;
def err_init_list_bad_dest_type : Error<
"%select{|non-aggregate }0type %1 cannot be initialized with an initializer "
"list">;
-def err_member_function_call_bad_cvr : Error<"member function %0 not viable: "
- "'this' argument has type %1, but function is not marked "
- "%select{const|restrict|const or restrict|volatile|const or volatile|"
- "volatile or restrict|const, volatile, or restrict}2">;
def err_reference_bind_to_bitfield : Error<
"%select{non-const|volatile}0 reference cannot bind to "
@@ -1907,34 +1944,29 @@ def warn_unsequenced_mod_mod : Warning<
def warn_unsequenced_mod_use : Warning<
"unsequenced modification and access to %0">, InGroup<Unsequenced>;
+def select_initialized_entity_kind : TextSubstitution<
+ "%select{copying variable|copying parameter|"
+ "returning object|initializing statement expression result|"
+ "throwing object|copying member subobject|copying array element|"
+ "allocating object|copying temporary|initializing base subobject|"
+ "initializing vector element|capturing value}0">;
+
def err_temp_copy_no_viable : Error<
- "no viable constructor %select{copying variable|copying parameter|"
- "returning object|throwing object|copying member subobject|copying array "
- "element|allocating object|copying temporary|initializing base subobject|"
- "initializing vector element|capturing value}0 of type %1">;
+ "no viable constructor %sub{select_initialized_entity_kind}0 of type %1">;
def ext_rvalue_to_reference_temp_copy_no_viable : Extension<
- "no viable constructor %select{copying variable|copying parameter|"
- "returning object|throwing object|copying member subobject|copying array "
- "element|allocating object|copying temporary|initializing base subobject|"
- "initializing vector element|capturing value}0 of type %1; C++98 requires a copy "
- "constructor when binding a reference to a temporary">,
+ "no viable constructor %sub{select_initialized_entity_kind}0 of type %1; "
+ "C++98 requires a copy constructor when binding a reference to a temporary">,
InGroup<BindToTemporaryCopy>;
def err_temp_copy_ambiguous : Error<
- "ambiguous constructor call when %select{copying variable|copying "
- "parameter|returning object|throwing object|copying member subobject|copying "
- "array element|allocating object|copying temporary|initializing base subobject|"
- "initializing vector element|capturing value}0 of type %1">;
+ "ambiguous constructor call when %sub{select_initialized_entity_kind}0 "
+ "of type %1">;
def err_temp_copy_deleted : Error<
- "%select{copying variable|copying parameter|returning object|throwing "
- "object|copying member subobject|copying array element|allocating object|"
- "copying temporary|initializing base subobject|initializing vector element|"
- "capturing value}0 of type %1 invokes deleted constructor">;
+ "%sub{select_initialized_entity_kind}0 of type %1 "
+ "invokes deleted constructor">;
def err_temp_copy_incomplete : Error<
"copying a temporary object of incomplete type %0">;
def warn_cxx98_compat_temp_copy : Warning<
- "%select{copying variable|copying parameter|returning object|throwing "
- "object|copying member subobject|copying array element|allocating object|"
- "copying temporary|initializing base subobject|initializing vector element}1 "
+ "%sub{select_initialized_entity_kind}1 "
"of type %2 when binding a reference to a temporary would %select{invoke "
"an inaccessible constructor|find no viable constructor|find ambiguous "
"constructors|invoke a deleted constructor}0 in C++98">,
@@ -2031,10 +2063,6 @@ def err_implied_std_initializer_list_not_found : Error<
"not found; include <initializer_list>">;
def err_malformed_std_initializer_list : Error<
"std::initializer_list must be a class template with a single type parameter">;
-def warn_dangling_std_initializer_list : Warning<
- "array backing the initializer list will be destroyed at the end of "
- "%select{the full-expression|the constructor}0">,
- InGroup<DiagGroup<"dangling-initializer-list">>;
def err_auto_init_list_from_c : Error<
"cannot use __auto_type with initializer list in C">;
def err_auto_bitfield : Error<
@@ -2099,9 +2127,16 @@ def err_deduction_guide_explicit_mismatch : Error<
def err_deduction_guide_specialized : Error<"deduction guide cannot be "
"%select{explicitly instantiated|explicitly specialized}0">;
def err_deduction_guide_template_not_deducible : Error<
- "deduction guide template contains "
- "%select{a template parameter|template parameters}0 that cannot be "
- "deduced">;
+ "deduction guide template contains "
+ "%select{a template parameter|template parameters}0 that cannot be "
+ "deduced">;
+def err_deduction_guide_wrong_access : Error<
+ "deduction guide has different access from the corresponding "
+ "member template">;
+def note_deduction_guide_template_access : Note<
+ "member template declared %0 here">;
+def note_deduction_guide_access : Note<
+ "deduction guide declared %0 by intervening access specifier">;
// C++1y deduced return types
def err_auto_fn_deduction_failure : Error<
@@ -2363,6 +2398,8 @@ def note_non_literal_user_provided_dtor : Note<
"%0 is not literal because it has a user-provided destructor">;
def note_non_literal_nontrivial_dtor : Note<
"%0 is not literal because it has a non-trivial destructor">;
+def note_non_literal_lambda : Note<
+ "lambda closure types are non-literal types before C++17">;
def warn_private_extern : Warning<
"use of __private_extern__ on a declaration may not produce external symbol "
"private to the linkage unit and is deprecated">, InGroup<PrivateExtern>;
@@ -2403,6 +2440,9 @@ def err_template_different_associated_constraints : Error<
def warn_cxx98_compat_unicode_type : Warning<
"'%0' type specifier is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
+def warn_cxx17_compat_unicode_type : Warning<
+ "'char8_t' type specifier is incompatible with C++ standards before C++20">,
+ InGroup<CXXPre2aCompat>, DefaultIgnore;
// __make_integer_seq
def err_integer_sequence_negative_length : Error<
@@ -2441,8 +2481,8 @@ def err_attribute_requires_positive_integer : Error<
def err_attribute_requires_opencl_version : Error<
"%0 attribute requires OpenCL version %1%select{| or above}2">;
def warn_unsupported_target_attribute
- : Warning<"ignoring %select{unsupported|duplicate}0"
- "%select{| architecture}1 '%2' in the target attribute string">,
+ : Warning<"%select{unsupported|duplicate}0%select{| architecture}1 '%2' in"
+ " the 'target' attribute string; 'target' attribute ignored">,
InGroup<IgnoredAttributes>;
def err_attribute_unsupported
: Error<"%0 attribute is not supported for this target">;
@@ -2546,6 +2586,9 @@ def err_attribute_address_space_too_high : Error<
"address space is larger than the maximum supported (%0)">;
def err_attribute_address_multiple_qualifiers : Error<
"multiple address spaces specified for type">;
+def warn_attribute_address_multiple_identical_qualifiers : Warning<
+ "multiple identical address spaces specified for type">,
+ InGroup<DuplicateDeclSpecifier>;
def err_attribute_address_function_type : Error<
"function type may not be qualified with an address space">;
def err_as_qualified_auto_decl : Error<
@@ -2639,11 +2682,19 @@ def err_only_annotate_after_access_spec : Error<
"access specifier can only have annotation attributes">;
def err_attribute_section_invalid_for_target : Error<
- "argument to 'section' attribute is not valid for this target: %0">;
+ "argument to %select{'code_seg'|'section'}1 attribute is not valid for this target: %0">;
def warn_mismatched_section : Warning<
- "section does not match previous declaration">, InGroup<Section>;
+ "%select{codeseg|section}0 does not match previous declaration">, InGroup<Section>;
def warn_attribute_section_on_redeclaration : Warning<
"section attribute is specified on redeclared variable">, InGroup<Section>;
+def err_mismatched_code_seg_base : Error<
+ "derived class must specify the same code segment as its base classes">;
+def err_mismatched_code_seg_override : Error<
+ "overriding virtual function must specify the same code segment as its overridden function">;
+def err_conflicting_codeseg_attribute : Error<
+ "conflicting code segment specifiers">;
+def warn_duplicate_codeseg_attribute : Warning<
+ "duplicate code segment specifiers">, InGroup<Section>;
def err_anonymous_property: Error<
"anonymous property is not supported">;
@@ -2683,6 +2734,9 @@ def warn_attribute_ignored : Warning<"%0 attribute ignored">,
def warn_attribute_ignored_on_inline :
Warning<"%0 attribute ignored on inline function">,
InGroup<IgnoredAttributes>;
+def warn_nocf_check_attribute_ignored :
+ Warning<"'nocf_check' attribute ignored; use -fcf-protection to enable the attribute">,
+ InGroup<IgnoredAttributes>;
def warn_attribute_after_definition_ignored : Warning<
"attribute %0 after definition is ignored">,
InGroup<IgnoredAttributes>;
@@ -2796,7 +2850,7 @@ def warn_alias_with_section : Warning<
"%select{alias|ifunc}1 will not be in section '%0' but in the same section as the %select{aliasee|resolver}2">,
InGroup<IgnoredAttributes>;
def err_duplicate_mangled_name : Error<
- "definition with same mangled name as another definition">;
+ "definition with same mangled name '%0' as another definition">;
def err_cyclic_alias : Error<
"%select{alias|ifunc}0 definition is part of a cycle">;
def err_ifunc_resolver_return : Error<
@@ -2821,8 +2875,7 @@ def warn_attribute_wrong_decl_type : Warning<
"|types and namespaces"
"|variables, functions and classes"
"|kernel functions"
- "|non-K&R-style functions"
- "|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members}1">,
+ "|non-K&R-style functions}1">,
InGroup<IgnoredAttributes>;
def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
def warn_type_attribute_wrong_type : Warning<
@@ -2877,6 +2930,9 @@ def err_base_specifier_attribute : Error<
def err_invalid_attribute_on_virtual_function : Error<
"%0 attribute cannot be applied to virtual functions">;
+def ext_cannot_use_trivial_abi : ExtWarn<
+ "'trivial_abi' cannot be applied to %0">, InGroup<IgnoredAttributes>;
+
// Availability attribute
def warn_availability_unknown_platform : Warning<
"unknown platform %0 in availability macro">, InGroup<Availability>;
@@ -2896,6 +2952,10 @@ def warn_mismatched_availability_override_unavail : Warning<
"%select{the protocol method it implements|its overridden method}1 is "
"available">,
InGroup<Availability>;
+def warn_availability_on_static_initializer : Warning<
+ "ignoring availability attribute %select{on '+load' method|"
+ "with constructor attribute|with destructor attribute}0">,
+ InGroup<Availability>;
def note_overridden_method : Note<
"overridden method is here">;
def note_protocol_method : Note<
@@ -2970,11 +3030,11 @@ def warn_lock_exclusive_and_shared : Warning<
def note_lock_exclusive_and_shared : Note<
"the other acquisition of %0 '%1' is here">;
def warn_variable_requires_any_lock : Warning<
- "%select{reading|writing}1 variable '%0' requires holding "
+ "%select{reading|writing}1 variable %0 requires holding "
"%select{any mutex|any mutex exclusively}1">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_var_deref_requires_any_lock : Warning<
- "%select{reading|writing}1 the value pointed to by '%0' requires holding "
+ "%select{reading|writing}1 the value pointed to by %0 requires holding "
"%select{any mutex|any mutex exclusively}1">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_fun_excludes_mutex : Warning<
@@ -2998,25 +3058,25 @@ def warn_acquire_requires_negative_cap : Warning<
// Thread safety warnings on pass by reference
def warn_guarded_pass_by_reference : Warning<
- "passing variable '%1' by reference requires holding %0 "
+ "passing variable %1 by reference requires holding %0 "
"%select{'%2'|'%2' exclusively}3">,
InGroup<ThreadSafetyReference>, DefaultIgnore;
def warn_pt_guarded_pass_by_reference : Warning<
- "passing the value that '%1' points to by reference requires holding %0 "
+ "passing the value that %1 points to by reference requires holding %0 "
"%select{'%2'|'%2' exclusively}3">,
InGroup<ThreadSafetyReference>, DefaultIgnore;
// Imprecise thread safety warnings
def warn_variable_requires_lock : Warning<
- "%select{reading|writing}3 variable '%1' requires holding %0 "
+ "%select{reading|writing}3 variable %1 requires holding %0 "
"%select{'%2'|'%2' exclusively}3">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_var_deref_requires_lock : Warning<
- "%select{reading|writing}3 the value pointed to by '%1' requires "
+ "%select{reading|writing}3 the value pointed to by %1 requires "
"holding %0 %select{'%2'|'%2' exclusively}3">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
def warn_fun_requires_lock : Warning<
- "calling function '%1' requires holding %0 %select{'%2'|'%2' exclusively}3">,
+ "calling function %1 requires holding %0 %select{'%2'|'%2' exclusively}3">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
// Precise thread safety warnings
@@ -3034,7 +3094,7 @@ def note_found_mutex_near_match : Note<"found near match '%0'">;
// Verbose thread safety warnings
def warn_thread_safety_verbose : Warning<"Thread safety verbose warning.">,
InGroup<ThreadSafetyVerbose>, DefaultIgnore;
-def note_thread_warning_in_fun : Note<"Thread warning in function '%0'">;
+def note_thread_warning_in_fun : Note<"Thread warning in function %0">;
def note_guarded_by_declared_here : Note<"Guarded_by declared here.">;
// Dummy warning that will trigger "beta" warnings from the analysis if enabled.
@@ -3082,6 +3142,9 @@ def err_impcast_complex_scalar : Error<
def warn_impcast_float_precision : Warning<
"implicit conversion loses floating-point precision: %0 to %1">,
InGroup<Conversion>, DefaultIgnore;
+def warn_impcast_float_result_precision : Warning<
+ "implicit conversion when assigning computation result loses floating-point precision: %0 to %1">,
+ InGroup<Conversion>, DefaultIgnore;
def warn_impcast_double_promotion : Warning<
"implicit conversion increases floating-point precision: %0 to %1">,
InGroup<DoublePromotion>, DefaultIgnore;
@@ -3107,13 +3170,18 @@ def warn_impcast_bitfield_precision_constant : Warning<
def warn_impcast_literal_float_to_integer : Warning<
"implicit conversion from %0 to %1 changes value from %2 to %3">,
InGroup<LiteralConversion>;
+def warn_impcast_literal_float_to_integer_out_of_range : Warning<
+ "implicit conversion of out of range value from %0 to %1 is undefined">,
+ InGroup<LiteralConversion>;
def warn_impcast_float_integer : Warning<
"implicit conversion turns floating-point number into integer: %0 to %1">,
InGroup<FloatConversion>, DefaultIgnore;
def warn_impcast_float_to_integer : Warning<
- "implicit conversion of out of range value from %0 to %1 changes value "
- "from %2 to %3">,
+ "implicit conversion from %0 to %1 changes value from %2 to %3">,
+ InGroup<FloatOverflowConversion>, DefaultIgnore;
+def warn_impcast_float_to_integer_out_of_range : Warning<
+ "implicit conversion of out of range value from %0 to %1 is undefined">,
InGroup<FloatOverflowConversion>, DefaultIgnore;
def warn_impcast_float_to_integer_zero : Warning<
"implicit conversion from %0 to %1 changes non-zero value from %2 to %3">,
@@ -3303,6 +3371,9 @@ def err_attribute_not_supported_in_lang : Error<
"%0 attribute is not supported in %select{C|C++|Objective-C}1">;
def err_attribute_not_supported_on_arch
: Error<"%0 attribute is not supported on '%1'">;
+def warn_gcc_ignores_type_attr : Warning<
+ "GCC does not allow the %0 attribute to be written on a type">,
+ InGroup<GccCompat>;
// Clang-Specific Attributes
def warn_attribute_iboutlet : Warning<
@@ -3484,27 +3555,29 @@ def err_ovl_deleted_member_call : Error<
def note_ovl_too_many_candidates : Note<
"remaining %0 candidate%s0 omitted; "
"pass -fshow-overloads=all to show them">;
-def note_ovl_candidate : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "is the implicit default constructor|"
- "is the implicit copy constructor|"
- "is the implicit move constructor|"
- "is the implicit copy assignment operator|"
- "is the implicit move assignment operator|"
- "inherited constructor|"
- "inherited constructor }0%2"
- "%select{| has different class%diff{ (expected $ but has $)|}4,5"
- "| has different number of parameters (expected %4 but has %5)"
- "| has type mismatch at %ordinal4 parameter"
- "%diff{ (expected $ but has $)|}5,6"
- "| has different return type%diff{ ($ expected but has $)|}4,5"
+
+def select_ovl_candidate_kind : TextSubstitution<
+ "%select{function|function|constructor|"
+ "constructor (the implicit default constructor)|"
+ "constructor (the implicit copy constructor)|"
+ "constructor (the implicit move constructor)|"
+ "function (the implicit copy assignment operator)|"
+ "function (the implicit move assignment operator)|"
+ "inherited constructor}0%select{| template| %2}1">;
+
+def note_ovl_candidate : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,3"
+ "%select{| has different class%diff{ (expected $ but has $)|}5,6"
+ "| has different number of parameters (expected %5 but has %6)"
+ "| has type mismatch at %ordinal5 parameter"
+ "%diff{ (expected $ but has $)|}6,7"
+ "| has different return type%diff{ ($ expected but has $)|}5,6"
"| has different qualifiers (expected "
"%select{none|const|restrict|const and restrict|volatile|const and volatile"
- "|volatile and restrict|const, volatile, and restrict}4 but found "
+ "|volatile and restrict|const, volatile, and restrict}5 but found "
"%select{none|const|restrict|const and restrict|volatile|const and volatile"
- "|volatile and restrict|const, volatile, and restrict}5)"
- "| has different exception specification}3">;
+ "|volatile and restrict|const, volatile, and restrict}6)"
+ "| has different exception specification}4">;
def note_ovl_candidate_inherited_constructor : Note<
"constructor from base class %0 inherited here">;
@@ -3518,6 +3591,9 @@ def note_ovl_candidate_bad_deduction : Note<
"candidate template ignored: failed template argument deduction">;
def note_ovl_candidate_incomplete_deduction : Note<"candidate template ignored: "
"couldn't infer template argument %0">;
+def note_ovl_candidate_incomplete_deduction_pack : Note<"candidate template ignored: "
+ "deduced too few arguments for expanded pack %0; no argument for %ordinal1 "
+ "expanded parameter in deduced argument pack %2">;
def note_ovl_candidate_inconsistent_deduction : Note<
"candidate template ignored: deduced conflicting %select{types|values|"
"templates}0 for parameter %1%diff{ ($ vs. $)|}2,3">;
@@ -3574,233 +3650,99 @@ def note_ovl_candidate_non_deduced_mismatch_qualified : Note<
// Note that we don't treat templates differently for this diagnostic.
def note_ovl_candidate_arity : Note<"candidate "
- "%select{function|function|constructor|function|function|constructor|"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor}0 %select{|template }1"
- "not viable: requires%select{ at least| at most|}2 %3 argument%s3, but %4 "
- "%plural{1:was|:were}4 provided">;
+ "%sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "requires%select{ at least| at most|}3 %4 argument%s4, but %5 "
+ "%plural{1:was|:were}5 provided">;
def note_ovl_candidate_arity_one : Note<"candidate "
- "%select{function|function|constructor|function|function|constructor|"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor}0 %select{|template }1not viable: "
- "%select{requires at least|allows at most single|requires single}2 "
- "argument %3, but %plural{0:no|:%4}4 arguments were provided">;
+ "%sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "%select{requires at least|allows at most single|requires single}3 "
+ "argument %4, but %plural{0:no|:%5}5 arguments were provided">;
def note_ovl_candidate_deleted : Note<
- "candidate %select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1 has been "
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 has been "
"%select{explicitly made unavailable|explicitly deleted|"
- "implicitly deleted}2">;
+ "implicitly deleted}3">;
// Giving the index of the bad argument really clutters this message, and
// it's relatively unimportant because 1) it's generally obvious which
// argument(s) are of the given object type and 2) the fix is usually
// to complete the type, which doesn't involve changes to the call line
// anyway. If people complain, we can change it.
-def note_ovl_candidate_bad_conv_incomplete : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1 "
- "not viable: cannot convert argument of incomplete type "
- "%diff{$ to $|to parameter type}2,3 for "
- "%select{%ordinal5 argument|object argument}4"
+def note_ovl_candidate_bad_conv_incomplete : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "cannot convert argument of incomplete type "
+ "%diff{$ to $|to parameter type}3,4 for "
+ "%select{%ordinal6 argument|object argument}5"
"%select{|; dereference the argument with *|"
"; take the address of the argument with &|"
"; remove *|"
- "; remove &}6">;
-def note_ovl_candidate_bad_list_argument : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1 "
- "not viable: cannot convert initializer list argument to %3">;
-def note_ovl_candidate_bad_overload : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1"
- " not viable: no overload of %3 matching %2 for %ordinal4 argument">;
-def note_ovl_candidate_bad_conv : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1"
- " not viable: no known conversion "
- "%diff{from $ to $|from argument type to parameter type}2,3 for "
- "%select{%ordinal5 argument|object argument}4"
+ "; remove &}7">;
+def note_ovl_candidate_bad_list_argument : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "cannot convert initializer list argument to %4">;
+def note_ovl_candidate_bad_overload : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "no overload of %4 matching %3 for %ordinal5 argument">;
+def note_ovl_candidate_bad_conv : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "no known conversion "
+ "%diff{from $ to $|from argument type to parameter type}3,4 for "
+ "%select{%ordinal6 argument|object argument}5"
"%select{|; dereference the argument with *|"
"; take the address of the argument with &|"
"; remove *|"
- "; remove &}6">;
-def note_ovl_candidate_bad_arc_conv : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1"
- " not viable: cannot implicitly convert argument "
- "%diff{of type $ to $|type to parameter type}2,3 for "
- "%select{%ordinal5 argument|object argument}4 under ARC">;
-def note_ovl_candidate_bad_lvalue : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1"
- " not viable: expects an l-value for "
- "%select{%ordinal3 argument|object argument}2">;
-def note_ovl_candidate_bad_addrspace : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1 not viable: "
- "%select{%ordinal6|'this'}5 argument (%2) is in "
- "address space %3, but parameter must be in address space %4">;
-def note_ovl_candidate_bad_gc : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1 not viable: "
- "%select{%ordinal6|'this'}5 argument (%2) has %select{no|__weak|__strong}3 "
- "ownership, but parameter has %select{no|__weak|__strong}4 ownership">;
-def note_ovl_candidate_bad_ownership : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1 not viable: "
- "%select{%ordinal6|'this'}5 argument (%2) has "
- "%select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}3 ownership,"
+ "; remove &}7">;
+def note_ovl_candidate_bad_arc_conv : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "cannot implicitly convert argument "
+ "%diff{of type $ to $|type to parameter type}3,4 for "
+ "%select{%ordinal6 argument|object argument}5 under ARC">;
+def note_ovl_candidate_bad_lvalue : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "expects an l-value for "
+ "%select{%ordinal4 argument|object argument}3">;
+def note_ovl_candidate_bad_addrspace : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "address space mismatch in %select{%ordinal6|'this'}5 argument (%3), "
+ "parameter type must be %4">;
+def note_ovl_candidate_bad_gc : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "%select{%ordinal7|'this'}6 argument (%3) has %select{no|__weak|__strong}4 "
+ "ownership, but parameter has %select{no|__weak|__strong}5 ownership">;
+def note_ovl_candidate_bad_ownership : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "%select{%ordinal7|'this'}6 argument (%3) has "
+ "%select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}4 ownership,"
" but parameter has %select{no|__unsafe_unretained|__strong|__weak|"
- "__autoreleasing}4 ownership">;
-def note_ovl_candidate_bad_cvr_this : Note<"candidate "
- "%select{|function|||function|||||"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)||}0 not viable: "
- "'this' argument has type %2, but method is not marked "
+ "__autoreleasing}5 ownership">;
+def note_ovl_candidate_bad_cvr_this : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "'this' argument has type %3, but method is not marked "
"%select{const|restrict|const or restrict|volatile|const or volatile|"
- "volatile or restrict|const, volatile, or restrict}3">;
-def note_ovl_candidate_bad_cvr : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1 not viable: "
- "%ordinal4 argument (%2) would lose "
+ "volatile or restrict|const, volatile, or restrict}4">;
+def note_ovl_candidate_bad_cvr : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "%ordinal5 argument (%3) would lose "
"%select{const|restrict|const and restrict|volatile|const and volatile|"
- "volatile and restrict|const, volatile, and restrict}3 qualifier"
- "%select{||s||s|s|s}3">;
-def note_ovl_candidate_bad_unaligned : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1 not viable: "
- "%ordinal4 argument (%2) would lose __unaligned qualifier">;
-def note_ovl_candidate_bad_base_to_derived_conv : Note<"candidate "
- "%select{function|function|constructor|"
- "function |function |constructor |"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor }0%1 not viable: "
- "cannot %select{convert from|convert from|bind}2 "
- "%select{base class pointer|superclass|base class object of type}2 %3 to "
- "%select{derived class pointer|subclass|derived class reference}2 %4 for "
- "%ordinal5 argument">;
+ "volatile and restrict|const, volatile, and restrict}4 qualifier"
+ "%select{||s||s|s|s}4">;
+def note_ovl_candidate_bad_unaligned : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "%ordinal5 argument (%3) would lose __unaligned qualifier">;
+def note_ovl_candidate_bad_base_to_derived_conv : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "cannot %select{convert from|convert from|bind}3 "
+ "%select{base class pointer|superclass|base class object of type}3 %4 to "
+ "%select{derived class pointer|subclass|derived class reference}3 %5 for "
+ "%ordinal6 argument">;
def note_ovl_candidate_bad_target : Note<
- "candidate %select{function|function|constructor|"
- "function|function|constructor|"
- "constructor (the implicit default constructor)|"
- "constructor (the implicit copy constructor)|"
- "constructor (the implicit move constructor)|"
- "function (the implicit copy assignment operator)|"
- "function (the implicit move assignment operator)|"
- "inherited constructor|"
- "inherited constructor}0 not viable: "
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
"call to "
- "%select{__device__|__global__|__host__|__host__ __device__|invalid}1 function from"
- " %select{__device__|__global__|__host__|__host__ __device__|invalid}2 function">;
+ "%select{__device__|__global__|__host__|__host__ __device__|invalid}3 function from"
+ " %select{__device__|__global__|__host__|__host__ __device__|invalid}4 function">;
def note_implicit_member_target_infer_collision : Note<
- "implicit %select{"
- "default constructor|"
- "copy constructor|"
- "move constructor|"
- "copy assignment operator|"
- "move assignment operator|"
- "destructor}0 inferred target collision: call to both "
+ "implicit %sub{select_special_member_kind}0 inferred target collision: call to both "
"%select{__device__|__global__|__host__|__host__ __device__}1 and "
"%select{__device__|__global__|__host__|__host__ __device__}2 members">;
@@ -3842,16 +3784,14 @@ def err_ovl_deleted_oper : Error<
"overload resolution selected %select{unavailable|deleted}0 operator '%1'%2">;
def err_ovl_deleted_special_oper : Error<
"object of type %0 cannot be %select{constructed|copied|moved|assigned|"
- "assigned|destroyed}1 because its %select{default constructor|"
- "copy constructor|move constructor|copy assignment operator|"
- "move assignment operator|destructor}1 is implicitly deleted">;
+ "assigned|destroyed}1 because its %sub{select_special_member_kind}1 is implicitly deleted">;
def err_ovl_no_viable_subscript :
Error<"no viable overloaded operator[] for type %0">;
def err_ovl_no_oper :
Error<"type %0 does not provide a %select{subscript|call}1 operator">;
def err_ovl_unresolvable : Error<
- "reference to overloaded function could not be resolved; "
- "did you mean to call it%select{| with no arguments}0?">;
+ "reference to %select{overloaded|multiversioned}1 function could not be "
+ "resolved; did you mean to call it%select{| with no arguments}0?">;
def err_bound_member_function : Error<
"reference to non-static member function must be called"
"%select{|; did you mean to call it with no arguments?}0">;
@@ -3961,8 +3901,6 @@ def err_template_member_noparams : Error<
"extraneous 'template<>' in declaration of member %0">;
def err_template_tag_noparams : Error<
"extraneous 'template<>' in declaration of %0 %1">;
-def err_template_decl_ref : Error<
- "cannot refer to %select{class|variable}0 template %1 without a template argument list">;
// C++ Template Argument Lists
def err_template_missing_args : Error<
@@ -4130,42 +4068,20 @@ def note_explicit_specialization_declared_here : Note<
"explicit specialization declared here">;
def err_template_spec_decl_function_scope : Error<
"explicit specialization of %0 in function scope">;
-def err_template_spec_decl_class_scope : Error<
- "explicit specialization of %0 in class scope">;
def err_template_spec_decl_friend : Error<
"cannot declare an explicit specialization in a friend">;
-def err_template_spec_decl_out_of_scope_global : Error<
- "%select{class template|class template partial|variable template|"
- "variable template partial|function template|member function|"
- "static data member|member class|member enumeration}0 "
- "specialization of %1 must originally be declared in the global scope">;
-def err_template_spec_decl_out_of_scope : Error<
- "%select{class template|class template partial|variable template|"
- "variable template partial|function template|member "
- "function|static data member|member class|member enumeration}0 "
- "specialization of %1 must originally be declared in namespace %2">;
-def ext_template_spec_decl_out_of_scope : ExtWarn<
- "first declaration of %select{class template|class template partial|"
- "variable template|variable template partial|"
- "function template|member function|static data member|member class|"
- "member enumeration}0 specialization of %1 outside namespace %2 is a "
- "C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_template_spec_decl_out_of_scope : Warning<
- "%select{class template|class template partial|variable template|"
- "variable template partial|function template|member "
- "function|static data member|member class|member enumeration}0 "
- "specialization of %1 outside namespace %2 is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
def err_template_spec_redecl_out_of_scope : Error<
"%select{class template|class template partial|variable template|"
"variable template partial|function template|member "
"function|static data member|member class|member enumeration}0 "
- "specialization of %1 not in a namespace enclosing %2">;
+ "specialization of %1 not in %select{a namespace enclosing %2|"
+ "class %2 or an enclosing namespace}3">;
def ext_ms_template_spec_redecl_out_of_scope: ExtWarn<
"%select{class template|class template partial|variable template|"
"variable template partial|function template|member "
"function|static data member|member class|member enumeration}0 "
- "specialization of %1 outside namespace enclosing %2 "
+ "specialization of %1 not in %select{a namespace enclosing %2|"
+ "class %2 or an enclosing namespace}3 "
"is a Microsoft extension">, InGroup<MicrosoftTemplate>;
def err_template_spec_redecl_global_scope : Error<
"%select{class template|class template partial|variable template|"
@@ -4187,16 +4103,18 @@ def err_template_spec_default_arg : Error<
def err_not_class_template_specialization : Error<
"cannot specialize a %select{dependent template|template template "
"parameter}0">;
-def err_function_specialization_in_class : Error<
- "cannot specialize a function %0 within class scope">;
-def ext_function_specialization_in_class : ExtWarn<
- "explicit specialization of %0 within class scope is a Microsoft extension">,
- InGroup<MicrosoftTemplate>;
def ext_explicit_specialization_storage_class : ExtWarn<
"explicit specialization cannot have a storage class">;
def err_explicit_specialization_inconsistent_storage_class : Error<
"explicit specialization has extraneous, inconsistent storage class "
"'%select{none|extern|static|__private_extern__|auto|register}0'">;
+def err_dependent_function_template_spec_no_match : Error<
+ "no candidate function template was found for dependent"
+ " friend function template specialization">;
+def note_dependent_function_template_spec_discard_reason : Note<
+ "candidate ignored: %select{not a function template"
+ "|not a member of the enclosing namespace;"
+ " did you mean to explicitly qualify the specialization?}0">;
// C++ class template specializations and out-of-line definitions
def err_template_spec_needs_header : Error<
@@ -4493,6 +4411,8 @@ def note_using_value_decl_missing_typename : Note<
def err_template_kw_refers_to_non_template : Error<
"%0 following the 'template' keyword does not refer to a template">;
+def note_template_kw_refers_to_non_template : Note<
+ "declared as a non-template here">;
def err_template_kw_refers_to_class_template : Error<
"'%0%1' instantiated to a class template, not a function template">;
def note_referenced_class_template : Note<
@@ -4554,6 +4474,9 @@ def err_pack_expansion_length_conflict : Error<
def err_pack_expansion_length_conflict_multilevel : Error<
"pack expansion contains parameter pack %0 that has a different "
"length (%1 vs. %2) from outer parameter packs">;
+def err_pack_expansion_length_conflict_partial : Error<
+ "pack expansion contains parameter pack %0 that has a different "
+ "length (at least %1 vs. %2) from outer parameter packs">;
def err_pack_expansion_member_init : Error<
"pack expansion for initialization of member %0">;
@@ -5112,12 +5035,17 @@ def note_protected_by_objc_strong_init : Note<
"jump bypasses initialization of __strong variable">;
def note_protected_by_objc_weak_init : Note<
"jump bypasses initialization of __weak variable">;
+def note_protected_by_non_trivial_c_struct_init : Note<
+ "jump bypasses initialization of variable of non-trivial C struct type">;
def note_enters_block_captures_cxx_obj : Note<
"jump enters lifetime of block which captures a destructible C++ object">;
def note_enters_block_captures_strong : Note<
"jump enters lifetime of block which strongly captures a variable">;
def note_enters_block_captures_weak : Note<
"jump enters lifetime of block which weakly captures a variable">;
+def note_enters_block_captures_non_trivial_c_struct : Note<
+ "jump enters lifetime of block which captures a C struct that is non-trivial "
+ "to destroy">;
def note_exits_cleanup : Note<
"jump exits scope of variable with __attribute__((cleanup))">;
@@ -5158,6 +5086,9 @@ def note_exits_block_captures_strong : Note<
"jump exits lifetime of block which strongly captures a variable">;
def note_exits_block_captures_weak : Note<
"jump exits lifetime of block which weakly captures a variable">;
+def note_exits_block_captures_non_trivial_c_struct : Note<
+ "jump exits lifetime of block which captures a C struct that is non-trivial "
+ "to destroy">;
def err_func_returning_qualified_void : ExtWarn<
"function cannot return qualified void type %0">,
@@ -5411,8 +5342,6 @@ def warn_block_capture_autoreleasing : Warning<
"block captures an autoreleasing out-parameter, which may result in "
"use-after-free bugs">,
InGroup<BlockCaptureAutoReleasing>;
-def note_declare_parameter_autoreleasing : Note<
- "declare the parameter __autoreleasing explicitly to suppress this warning">;
def note_declare_parameter_strong : Note<
"declare the parameter __strong or capture a __block __strong variable to "
"keep values alive across autorelease pools">;
@@ -5601,9 +5530,12 @@ def warn_addition_in_bitshift : Warning<
"operator '%0' has lower precedence than '%1'; "
"'%1' will be evaluated first">, InGroup<ShiftOpParentheses>;
-def warn_self_assignment : Warning<
+def warn_self_assignment_builtin : Warning<
"explicitly assigning value of variable of type %0 to itself">,
InGroup<SelfAssignment>, DefaultIgnore;
+def warn_self_assignment_overloaded : Warning<
+ "explicitly assigning value of variable of type %0 to itself">,
+ InGroup<SelfAssignmentOverloaded>, DefaultIgnore;
def warn_self_move : Warning<
"explicitly moving variable of type %0 to itself">,
InGroup<SelfMove>, DefaultIgnore;
@@ -5619,6 +5551,19 @@ def warn_pessimizing_move_on_initialization : Warning<
InGroup<PessimizingMove>, DefaultIgnore;
def note_remove_move : Note<"remove std::move call here">;
+def warn_return_std_move : Warning<
+ "local variable %0 will be copied despite being %select{returned|thrown}1 by name">,
+ InGroup<ReturnStdMove>, DefaultIgnore;
+def note_add_std_move : Note<
+ "call 'std::move' explicitly to avoid copying">;
+def warn_return_std_move_in_cxx11 : Warning<
+ "prior to the resolution of a defect report against ISO C++11, "
+ "local variable %0 would have been copied despite being returned by name, "
+ "due to its not matching the function return type%diff{ ($ vs $)|}1,2">,
+ InGroup<ReturnStdMoveInCXX11>, DefaultIgnore;
+def note_add_std_move_in_cxx11 : Note<
+ "call 'std::move' explicitly to avoid copying on older compilers">;
+
def warn_string_plus_int : Warning<
"adding %0 to a string does not append to the string">,
InGroup<StringPlusInt>;
@@ -5797,6 +5742,13 @@ def err_array_init_wide_string_into_char : Error<
"initializing char array with wide string literal">;
def err_array_init_incompat_wide_string_into_wchar : Error<
"initializing wide char array with incompatible wide string literal">;
+def err_array_init_plain_string_into_char8_t : Error<
+ "initializing 'char8_t' array with plain string literal">;
+def note_array_init_plain_string_into_char8_t : Note<
+ "add 'u8' prefix to form a 'char8_t' string literal">;
+def err_array_init_utf8_string_into_char : Error<
+ "initialization of char array with UTF-8 string literal is not permitted "
+ "by '-fchar8_t'">;
def err_array_init_different_type : Error<
"cannot initialize array %diff{of type $ with array of type $|"
"with different type of array}0,1">;
@@ -5881,6 +5833,8 @@ def err_objc_object_assignment : Error<
"cannot assign to class object (%0 invalid)">;
def err_typecheck_invalid_operands : Error<
"invalid operands to binary expression (%0 and %1)">;
+def note_typecheck_invalid_operands_converted : Note<
+ "%select{first|second}0 operand was implicitly converted to type %1">;
def err_typecheck_logical_vector_expr_gnu_cpp_restrict : Error<
"logical expression with vector %select{type %1 and non-vector type %2|types"
" %1 and %2}0 is only supported in C++">;
@@ -5894,7 +5848,8 @@ def ext_typecheck_ordered_comparison_of_pointer_and_zero : Extension<
def err_typecheck_ordered_comparison_of_pointer_and_zero : Error<
"ordered comparison between pointer and zero (%0 and %1)">;
def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
- "ordered comparison of function pointers (%0 and %1)">;
+ "ordered comparison of function pointers (%0 and %1)">,
+ InGroup<DiagGroup<"ordered-compare-function-pointers">>;
def ext_typecheck_comparison_of_fptr_to_void : Extension<
"equality comparison between function pointer and void pointer (%0 and %1)">;
def err_typecheck_comparison_of_fptr_to_void : Error<
@@ -5942,15 +5897,15 @@ def note_typecheck_assign_const : Note<
def warn_unsigned_always_true_comparison : Warning<
"result of comparison of %select{%3|unsigned expression}0 %2 "
"%select{unsigned expression|%3}0 is always %4">,
- InGroup<TautologicalUnsignedZeroCompare>;
+ InGroup<TautologicalUnsignedZeroCompare>, DefaultIgnore;
def warn_unsigned_enum_always_true_comparison : Warning<
"result of comparison of %select{%3|unsigned enum expression}0 %2 "
"%select{unsigned enum expression|%3}0 is always %4">,
- InGroup<TautologicalUnsignedEnumZeroCompare>;
+ InGroup<TautologicalUnsignedEnumZeroCompare>, DefaultIgnore;
def warn_tautological_constant_compare : Warning<
"result of comparison %select{%3|%1}0 %2 "
"%select{%1|%3}0 is always %4">,
- InGroup<TautologicalConstantCompare>;
+ InGroup<TautologicalTypeLimitCompare>, DefaultIgnore;
def warn_mixed_sign_comparison : Warning<
"comparison of integers of different signs: %0 and %1">,
@@ -6186,9 +6141,9 @@ def err_objc_object_catch : Error<
def err_incomplete_type_objc_at_encode : Error<
"'@encode' of incomplete type %0">;
def warn_objc_circular_container : Warning<
- "adding '%0' to '%1' might cause circular dependency in container">,
+ "adding %0 to %1 might cause circular dependency in container">,
InGroup<DiagGroup<"objc-circular-container">>;
-def note_objc_circular_container_declared_here : Note<"'%0' declared here">;
+def note_objc_circular_container_declared_here : Note<"%0 declared here">;
def warn_objc_unsafe_perform_selector : Warning<
"%0 is incompatible with selectors that return a "
"%select{struct|union|vector}1 type">,
@@ -6260,6 +6215,12 @@ def err_bad_cxx_cast_bitfield : Error<
def err_bad_cxx_cast_qualifiers_away : Error<
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
"functional-style cast}0 from %1 to %2 casts away qualifiers">;
+def ext_bad_cxx_cast_qualifiers_away_incoherent : ExtWarn<
+ "ISO C++ does not allow "
+ "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
+ "functional-style cast}0 from %1 to %2 because it casts away qualifiers, "
+ "even though the source and destination types are unrelated">,
+ SFINAEFailure, InGroup<DiagGroup<"cast-qual-unrelated">>;
def err_bad_const_cast_dest : Error<
"%select{const_cast||||C-style cast|functional-style cast}0 to %2, "
"which is not a reference, pointer-to-object, or pointer-to-data-member">;
@@ -6440,6 +6401,8 @@ def err_bad_memptr_rhs : Error<
def err_bad_memptr_lhs : Error<
"left hand operand to %0 must be a %select{|pointer to }1class "
"compatible with the right hand operand, but is %2">;
+def err_memptr_incomplete : Error<
+ "member pointer has incomplete base type %0">;
def warn_exception_caught_by_earlier_handler : Warning<
"exception of type %0 will be caught by earlier handler">,
InGroup<Exceptions>;
@@ -6561,6 +6524,8 @@ let CategoryName = "Lambda Issue" in {
"lambda expression in an unevaluated operand">;
def err_lambda_in_constant_expression : Error<
"a lambda expression may not appear inside of a constant expression">;
+ def err_lambda_in_invalid_context : Error<
+ "a lambda expression cannot appear in this context">;
def err_lambda_return_init_list : Error<
"cannot deduce lambda return type from initializer list">;
def err_lambda_capture_default_arg : Error<
@@ -6619,6 +6584,11 @@ let CategoryName = "Lambda Issue" in {
def ext_equals_this_lambda_capture_cxx2a : ExtWarn<
"explicit capture of 'this' with a capture default of '=' "
"is a C++2a extension">, InGroup<CXX2a>;
+ def warn_deprecated_this_capture : Warning<
+ "implicit capture of 'this' with a capture default of '=' is deprecated">,
+ InGroup<DeprecatedThisCapture>, DefaultIgnore;
+ def note_deprecated_this_capture : Note<
+ "add an explicit capture of 'this' to capture '*this' by reference">;
}
def err_return_in_captured_stmt : Error<
@@ -6688,9 +6658,9 @@ def err_not_tag_in_scope : Error<
"no %select{struct|interface|union|class|enum}0 named %1 in %2">;
def err_no_typeid_with_fno_rtti : Error<
- "cannot use typeid with -fno-rtti">;
+ "use of typeid requires -frtti">;
def err_no_dynamic_cast_with_fno_rtti : Error<
- "cannot use dynamic_cast with -fno-rtti">;
+ "use of dynamic_cast requires -frtti">;
def err_cannot_form_pointer_to_member_of_reference_type : Error<
"cannot form a pointer-to-member to member %0 of reference type %1">;
@@ -7055,6 +7025,8 @@ def err_atomic_builtin_must_be_pointer : Error<
def err_atomic_builtin_must_be_pointer_intptr : Error<
"address argument to atomic builtin must be a pointer to integer or pointer"
" (%0 invalid)">;
+def err_atomic_builtin_cannot_be_const : Error<
+ "address argument to atomic builtin cannot be const-qualified (%0 invalid)">;
def err_atomic_builtin_must_be_pointer_intfltptr : Error<
"address argument to atomic builtin must be a pointer to integer,"
" floating-point or pointer (%0 invalid)">;
@@ -7079,6 +7051,8 @@ def err_atomic_op_needs_trivial_copy : Error<
def err_atomic_op_needs_atomic_int_or_ptr : Error<
"address argument to atomic operation must be a pointer to %select{|atomic }0"
"integer or pointer (%1 invalid)">;
+def err_atomic_op_needs_int32_or_ptr : Error<
+ "address argument to atomic operation must be a pointer to signed or unsigned 32-bit integer">;
def err_atomic_op_bitwise_needs_atomic_int : Error<
"address argument to bitwise atomic operation must be a pointer to "
"%select{|atomic }0integer (%1 invalid)">;
@@ -7087,6 +7061,9 @@ def warn_atomic_op_has_invalid_memory_order : Warning<
InGroup<DiagGroup<"atomic-memory-ordering">>;
def err_atomic_op_has_invalid_synch_scope : Error<
"synchronization scope argument to atomic operation is invalid">;
+def warn_atomic_op_misaligned : Warning<
+ "misaligned or large atomic operation may incur significant performance penalty">,
+ InGroup<DiagGroup<"atomic-alignment">>;
def err_overflow_builtin_must_be_int : Error<
"operand argument to overflow builtin must be an integer (%0 invalid)">;
@@ -7137,7 +7114,7 @@ def err_va_arg_in_device : Error<
"CUDA device code does not support va_arg">;
def err_alias_not_supported_on_nvptx : Error<"CUDA does not support aliases">;
def err_cuda_unattributed_constexpr_cannot_overload_device : Error<
- "constexpr function '%0' without __host__ or __device__ attributes cannot "
+ "constexpr function %0 without __host__ or __device__ attributes cannot "
"overload __device__ function with same signature. Add a __host__ "
"attribute, or build with -fno-cuda-host-device-constexpr.">;
def note_cuda_conflicting_device_function_declared_here : Note<
@@ -7176,6 +7153,10 @@ def err_cannot_pass_objc_interface_to_vararg_format : Error<
"cannot pass object with interface type %1 by value to variadic "
"%select{function|block|method|constructor}2; expected type from format "
"string was %3">;
+def err_cannot_pass_non_trivial_c_struct_to_vararg : Error<
+ "cannot pass non-trivial C object of type %0 by value to variadic "
+ "%select{function|block|method|constructor}1">;
+
def err_cannot_pass_objc_interface_to_vararg : Error<
"cannot pass object with interface type %0 by value through variadic "
@@ -7623,6 +7604,11 @@ def err_destroying_operator_delete_not_usual : Error<
"alignment parameter">;
def note_implicit_delete_this_in_destructor_here : Note<
"while checking implicit 'delete this' for virtual destructor">;
+def err_builtin_operator_new_delete_not_usual : Error<
+ "call to '%select{__builtin_operator_new|__builtin_operator_delete}0' "
+ "selects non-usual %select{allocation|deallocation}0 function">;
+def note_non_usual_function_declared_here : Note<
+ "non-usual %0 declared here">;
// C++ literal operators
def err_literal_operator_outside_namespace : Error<
@@ -7705,9 +7691,8 @@ def err_defaulted_special_member_quals : Error<
"an explicitly-defaulted %select{copy|move}0 assignment operator may not "
"have 'const'%select{, 'constexpr'|}1 or 'volatile' qualifiers">;
def err_defaulted_special_member_volatile_param : Error<
- "the parameter for an explicitly-defaulted %select{<<ERROR>>|"
- "copy constructor|move constructor|copy assignment operator|"
- "move assignment operator|<<ERROR>>}0 may not be volatile">;
+ "the parameter for an explicitly-defaulted %sub{select_special_member_kind}0 "
+ "may not be volatile">;
def err_defaulted_special_member_move_const_param : Error<
"the parameter for an explicitly-defaulted move "
"%select{constructor|assignment operator}0 may not be const">;
@@ -7719,17 +7704,13 @@ def err_defaulted_copy_assign_not_ref : Error<
"the parameter for an explicitly-defaulted copy assignment operator must be an "
"lvalue reference type">;
def err_incorrect_defaulted_exception_spec : Error<
- "exception specification of explicitly defaulted %select{default constructor|"
- "copy constructor|move constructor|copy assignment operator|move assignment "
- "operator|destructor}0 does not match the "
- "calculated one">;
+ "exception specification of explicitly defaulted "
+ "%sub{select_special_member_kind}0 does not match the calculated one">;
def err_incorrect_defaulted_constexpr : Error<
- "defaulted definition of %select{default constructor|copy constructor|"
- "move constructor|copy assignment operator|move assignment operator}0 "
+ "defaulted definition of %sub{select_special_member_kind}0 "
"is not constexpr">;
def err_out_of_line_default_deletes : Error<
- "defaulting this %select{default constructor|copy constructor|move "
- "constructor|copy assignment operator|move assignment operator|destructor}0 "
+ "defaulting this %sub{select_special_member_kind}0 "
"would delete it after its first declaration">;
def warn_vbase_moved_multiple_times : Warning<
"defaulted move assignment operator of %0 will move assign virtual base "
@@ -7784,6 +7765,10 @@ def warn_format_argument_needs_cast : Warning<
"%select{values of type|enum values with underlying type}2 '%0' should not "
"be used as format arguments; add an explicit cast to %1 instead">,
InGroup<Format>;
+def warn_format_argument_needs_cast_pedantic : Warning<
+ "%select{values of type|enum values with underlying type}2 '%0' should not "
+ "be used as format arguments; add an explicit cast to %1 instead">,
+ InGroup<FormatPedantic>, DefaultIgnore;
def warn_printf_positional_arg_exceeds_data_args : Warning <
"data argument position '%0' exceeds the number of data arguments (%1)">,
InGroup<Format>;
@@ -7868,8 +7853,8 @@ def warn_null_ret : Warning<
// CHECK: returning address/reference of stack memory
def warn_ret_stack_addr_ref : Warning<
- "%select{address of|reference to}0 stack memory associated with local "
- "variable %1 returned">,
+ "%select{address of|reference to}0 stack memory associated with "
+ "%select{local variable|parameter}2 %1 returned">,
InGroup<ReturnStackAddress>;
def warn_ret_local_temp_addr_ref : Warning<
"returning %select{address of|reference to}0 local temporary object">,
@@ -7879,30 +7864,69 @@ def warn_ret_addr_label : Warning<
InGroup<ReturnStackAddress>;
def err_ret_local_block : Error<
"returning block that lives on the local stack">;
-def note_ref_var_local_bind : Note<
- "binding reference variable %0 here">;
+def note_local_var_initializer : Note<
+ "%select{via initialization of|binding reference}0 variable %1 here">;
+def note_init_with_default_member_initalizer : Note<
+ "initializing field %0 with default member initializer">;
// Check for initializing a member variable with the address or a reference to
// a constructor parameter.
def warn_bind_ref_member_to_parameter : Warning<
- "binding reference member %0 to stack allocated parameter %1">,
- InGroup<DanglingField>;
+ "binding reference member %0 to stack allocated "
+ "%select{variable|parameter}2 %1">, InGroup<DanglingField>;
def warn_init_ptr_member_to_parameter_addr : Warning<
- "initializing pointer member %0 with the stack address of parameter %1">,
- InGroup<DanglingField>;
-def warn_bind_ref_member_to_temporary : Warning<
- "binding reference %select{|subobject of }1member %0 to a temporary value">,
- InGroup<DanglingField>;
+ "initializing pointer member %0 with the stack address of "
+ "%select{variable|parameter}2 %1">, InGroup<DanglingField>;
def note_ref_or_ptr_member_declared_here : Note<
"%select{reference|pointer}0 member declared here">;
-def note_ref_subobject_of_member_declared_here : Note<
- "member with reference subobject declared here">;
+
+def err_dangling_member : Error<
+ "%select{reference|backing array for 'std::initializer_list'}2 "
+ "%select{|subobject of }1member %0 "
+ "%select{binds to|is}2 a temporary object "
+ "whose lifetime would be shorter than the lifetime of "
+ "the constructed object">;
+def warn_dangling_member : Warning<
+ "%select{reference|backing array for 'std::initializer_list'}2 "
+ "%select{|subobject of }1member %0 "
+ "%select{binds to|is}2 a temporary object "
+ "whose lifetime is shorter than the lifetime of the constructed object">,
+ InGroup<DanglingField>;
+def note_lifetime_extending_member_declared_here : Note<
+ "%select{%select{reference|'std::initializer_list'}0 member|"
+ "member with %select{reference|'std::initializer_list'}0 subobject}1 "
+ "declared here">;
+def warn_dangling_variable : Warning<
+ "%select{temporary %select{whose address is used as value of|bound to}3 "
+ "%select{%select{|reference }3member of local variable|"
+ "local %select{variable|reference}3}1|"
+ "array backing "
+ "%select{initializer list subobject of local variable|"
+ "local initializer list}1}0 "
+ "%2 will be destroyed at the end of the full-expression">,
+ InGroup<Dangling>;
+def warn_new_dangling_reference : Warning<
+ "temporary bound to reference member of allocated object "
+ "will be destroyed at the end of the full-expression">,
+ InGroup<DanglingField>;
+def warn_new_dangling_initializer_list : Warning<
+ "array backing "
+ "%select{initializer list subobject of the allocated object|"
+ "the allocated initializer list}0 "
+ "will be destroyed at the end of the full-expression">,
+ InGroup<DanglingInitializerList>;
+def warn_unsupported_lifetime_extension : Warning<
+ "sorry, lifetime extension of "
+ "%select{temporary|backing array of initializer list}0 created "
+ "by aggregate initialization using default member initializer "
+ "is not supported; lifetime of %select{temporary|backing array}0 "
+ "will end at the end of the full-expression">, InGroup<Dangling>;
// For non-floating point, expressions of the form x == x or x != x
// should result in a warning, since these always evaluate to a constant.
// Array comparisons have similar warnings
def warn_comparison_always : Warning<
- "%select{self-|array }0comparison always evaluates to %select{false|true|a constant}1">,
+ "%select{self-|array }0comparison always evaluates to %select{a constant|%2}1">,
InGroup<TautologicalCompare>;
def warn_comparison_bitwise_always : Warning<
"bitwise comparison always evaluates to %select{false|true}0">,
@@ -7958,7 +7982,7 @@ def err_generic_sel_multi_match : Error<
// Blocks
def err_blocks_disable : Error<"blocks support disabled - compile with -fblocks"
- " or %select{pick a deployment target that supports them|for OpenCL 2.0 or above}0">;
+ " or %select{pick a deployment target that supports them|for OpenCL 2.0}0">;
def err_block_returning_array_function : Error<
"block cannot return %select{array|function}0 type %1">;
@@ -8197,7 +8221,10 @@ def err_altivec_empty_initializer : Error<"expected initializer">;
def err_invalid_neon_type_code : Error<
"incompatible constant for this __builtin_neon function">;
def err_argument_invalid_range : Error<
- "argument should be a value from %0 to %1">;
+ "argument value %0 is outside the valid range [%1, %2]">;
+def warn_argument_invalid_range : Warning<
+ "argument value %0 is outside the valid range [%1, %2]">, DefaultError,
+ InGroup<DiagGroup<"argument-outside-range">>;
def err_argument_not_multiple : Error<
"argument should be a multiple of %0">;
def warn_neon_vector_initializer_non_portable : Warning<
@@ -8214,6 +8241,8 @@ def err_systemz_invalid_tabort_code : Error<
"invalid transaction abort code">;
def err_64_bit_builtin_32_bit_tgt : Error<
"this builtin is only available on 64-bit targets">;
+def err_32_bit_builtin_64_bit_tgt : Error<
+ "this builtin is only available on 32-bit targets">;
def err_builtin_x64_aarch64_only : Error<
"this builtin is only available on x86-64 and aarch64 targets">;
def err_ppc_builtin_only_on_pwr7 : Error<
@@ -8222,7 +8251,15 @@ def err_x86_builtin_invalid_rounding : Error<
"invalid rounding argument">;
def err_x86_builtin_invalid_scale : Error<
"scale argument must be 1, 2, 4, or 8">;
-
+def err_hexagon_builtin_unsupported_cpu : Error<
+ "builtin is not supported on this CPU">;
+def err_hexagon_builtin_requires_hvx : Error<
+ "builtin requires HVX">;
+def err_hexagon_builtin_unsupported_hvx : Error<
+ "builtin is not supported on this version of HVX">;
+
+def err_builtin_target_unsupported : Error<
+ "builtin is not supported on this target">;
def err_builtin_longjmp_unsupported : Error<
"__builtin_longjmp is not supported for the current target">;
def err_builtin_setjmp_unsupported : Error<
@@ -8296,12 +8333,16 @@ def err_c99_array_usage_cxx : Error<
"feature, not permitted in C++">;
def err_type_unsupported : Error<
"%0 is not supported on this target">;
-def warn_nsconsumed_attribute_mismatch : Warning<
+def err_nsconsumed_attribute_mismatch : Error<
"overriding method has mismatched ns_consumed attribute on its"
- " parameter">, InGroup<NSConsumedMismatch>;
-def warn_nsreturns_retained_attribute_mismatch : Warning<
+ " parameter">;
+def err_nsreturns_retained_attribute_mismatch : Error<
"overriding method has mismatched ns_returns_%select{not_retained|retained}0"
- " attributes">, InGroup<NSReturnsMismatch>;
+ " attributes">;
+def warn_nsconsumed_attribute_mismatch : Warning<
+ err_nsconsumed_attribute_mismatch.Text>, InGroup<NSConsumedMismatch>;
+def warn_nsreturns_retained_attribute_mismatch : Warning<
+ err_nsreturns_retained_attribute_mismatch.Text>, InGroup<NSReturnsMismatch>;
def note_getter_unavailable : Note<
"or because setter is declared here, but no getter method %0 is found">;
@@ -8497,7 +8538,7 @@ def err_reference_pipe_type : Error <
"pipes packet types cannot be of reference type">;
def err_opencl_no_main : Error<"%select{function|kernel}0 cannot be called 'main'">;
def err_opencl_kernel_attr :
- Error<"attribute %0 can only be applied to a kernel function">;
+ Error<"attribute %0 can only be applied to an OpenCL kernel function">;
def err_opencl_return_value_with_address_space : Error<
"return value cannot be qualified with address space">;
def err_opencl_constant_no_init : Error<
@@ -8545,7 +8586,8 @@ def note_opencl_typedef_access_qualifier : Note<
// OpenCL Section 6.8.g
def err_opencl_unknown_type_specifier : Error<
- "OpenCL version %0 does not support the '%1' %select{type qualifier|storage class specifier}2">;
+ "OpenCL %select{C|C++}0 version %1 does not support the '%2' "
+ "%select{type qualifier|storage class specifier}3">;
// OpenCL v2.0 s6.12.5 Blocks restrictions
def err_opencl_block_storage_type : Error<
@@ -8635,8 +8677,8 @@ def err_omp_pointer_mapped_along_with_derived_section : Error<
"pointer cannot be mapped along with a section derived from itself">;
def err_omp_original_storage_is_shared_and_does_not_contain : Error<
"original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage">;
-def err_omp_same_pointer_derreferenced : Error<
- "same pointer derreferenced in multiple different ways in map clause expressions">;
+def err_omp_same_pointer_dereferenced : Error<
+ "same pointer dereferenced in multiple different ways in map clause expressions">;
def note_omp_task_predetermined_firstprivate_here : Note<
"predetermined as a firstprivate in a task construct here">;
def err_omp_threadprivate_incomplete_type : Error<
@@ -8972,6 +9014,9 @@ def err_omp_reduction_vla_unsupported : Error<
"cannot generate code for reduction on %select{|array section, which requires a }0variable length array">;
def err_omp_linear_distribute_var_non_loop_iteration : Error<
"only loop iteration variables are allowed in 'linear' clause in distribute directives">;
+def warn_omp_non_trivial_type_mapped : Warning<
+ "Non-trivial type %0 is mapped, only trivial types are guaranteed to be mapped correctly">,
+ InGroup<OpenMPTarget>;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
@@ -9072,9 +9117,9 @@ def note_equivalent_internal_linkage_decl : Note<
"declared here%select{ in module '%1'|}0">;
def note_redefinition_modules_same_file : Note<
- "'%0' included multiple times, additional include site in header from module '%1'">;
+ "'%0' included multiple times, additional include site in header from module '%1'">;
def note_redefinition_include_same_file : Note<
- "'%0' included multiple times, additional include site here">;
+ "'%0' included multiple times, additional include site here">;
}
let CategoryName = "Coroutines Issue" in {
@@ -9115,7 +9160,7 @@ def err_coroutine_promise_type_incomplete : Error<
"this function cannot be a coroutine: %0 is an incomplete type">;
def err_coroutine_type_missing_specialization : Error<
"this function cannot be a coroutine: missing definition of "
- "specialization %q0">;
+ "specialization %0">;
def err_coroutine_promise_incompatible_return_functions : Error<
"the coroutine promise type %0 declares both 'return_value' and 'return_void'">;
def err_coroutine_promise_requires_return_function : Error<
@@ -9320,8 +9365,67 @@ def ext_warn_gnu_final : ExtWarn<
InGroup<GccCompat>;
def warn_shadow_field :
- Warning<"non-static data member '%0' of '%1' shadows member inherited from type '%2'">,
+ Warning<"non-static data member %0 of %1 shadows member inherited from "
+ "type %2">,
InGroup<ShadowField>, DefaultIgnore;
def note_shadow_field : Note<"declared here">;
+def err_multiversion_required_in_redecl : Error<
+ "function declaration is missing %select{'target'|'cpu_specific' or "
+ "'cpu_dispatch'}0 attribute in a multiversioned function">;
+def note_multiversioning_caused_here : Note<
+ "function multiversioning caused by this declaration">;
+def err_multiversion_after_used : Error<
+ "function declaration cannot become a multiversioned function after first "
+ "usage">;
+def err_bad_multiversion_option : Error<
+ "function multiversioning doesn't support %select{feature|architecture}0 "
+ "'%1'">;
+def err_multiversion_duplicate : Error<
+ "multiversioned function redeclarations require identical target attributes">;
+def err_multiversion_noproto : Error<
+ "multiversioned function must have a prototype">;
+def err_multiversion_no_other_attrs : Error<
+ "attribute '%select{target|cpu_specific|cpu_dispatch}0' multiversioning cannot be combined"
+ " with other attributes">;
+def err_multiversion_diff : Error<
+ "multiversioned function declaration has a different %select{calling convention"
+ "|return type|constexpr specification|inline specification|storage class|"
+ "linkage}0">;
+def err_multiversion_doesnt_support : Error<
+ "attribute '%select{target|cpu_specific|cpu_dispatch}0' multiversioned functions do not "
+ "yet support %select{function templates|virtual functions|"
+ "deduced return types|constructors|destructors|deleted functions|"
+ "defaulted functions|constexpr functions}1">;
+def err_multiversion_not_allowed_on_main : Error<
+ "'main' cannot be a multiversioned function">;
+def err_multiversion_not_supported : Error<
+ "function multiversioning is not supported on the current target">;
+def err_multiversion_types_mixed : Error<
+ "multiversioning attributes cannot be combined">;
+def err_cpu_dispatch_mismatch : Error<
+ "'cpu_dispatch' function redeclared with different CPUs">;
+def err_cpu_specific_multiple_defs : Error<
+ "multiple 'cpu_specific' functions cannot specify the same CPU: %0">;
+def warn_multiversion_duplicate_entries : Warning<
+ "CPU list contains duplicate entries; attribute ignored">,
+ InGroup<FunctionMultiVersioning>;
+def warn_dispatch_body_ignored : Warning<
+ "body of cpu_dispatch function will be ignored">,
+ InGroup<FunctionMultiVersioning>;
+
+// three-way comparison operator diagnostics
+def err_implied_comparison_category_type_not_found : Error<
+ "cannot deduce return type of 'operator<=>' because type '%0' was not found; "
+ "include <compare>">;
+def err_spaceship_argument_narrowing : Error<
+ "argument to 'operator<=>' "
+ "%select{cannot be narrowed from type %1 to %2|"
+ "evaluates to %1, which cannot be narrowed to type %2}0">;
+def err_std_compare_type_not_supported : Error<
+ "standard library implementation of %0 is not supported; "
+ "%select{member '%2' does not have expected form|"
+ "member '%2' is missing|"
+ "the type is not trivially copyable|"
+ "the type does not have the expected form}1">;
} // end of sema component.
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 250b49f2cac45..3a552e2f3db42 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -38,8 +38,8 @@ def err_pch_targetopt_mismatch : Error<
"PCH file was compiled for the %0 '%1' but the current translation "
"unit is being compiled for target '%2'">;
def err_pch_targetopt_feature_mismatch : Error<
- "%select{AST file|current translation unit}0 was compiled with the target "
- "feature'%1' but the %select{current translation unit is|AST file was}0 "
+ "%select{AST file was|current translation unit is}0 compiled with the target "
+ "feature '%1' but the %select{current translation unit is|AST file was}0 "
"not">;
def err_pch_langopt_mismatch : Error<"%0 was %select{disabled|enabled}1 in "
"PCH file but is currently %select{disabled|enabled}2">;
@@ -168,11 +168,11 @@ def err_module_odr_violation_mismatch_decl : Error<
"%select{definition in module '%2'|defined here}1 found "
"%select{end of class|public access specifier|private access specifier|"
"protected access specifier|static assert|field|method|type alias|typedef|"
- "data member|friend declaration}3">;
+ "data member|friend declaration|function template}3">;
def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found "
"%select{end of class|public access specifier|private access specifier|"
"protected access specifier|static assert|field|method|type alias|typedef|"
- "data member|friend declaration}1">;
+ "data member|friend declaration|function template}1">;
def err_module_odr_violation_mismatch_decl_diff : Error<
"%q0 has different definitions in different modules; first difference is "
@@ -192,6 +192,8 @@ def err_module_odr_violation_mismatch_decl_diff : Error<
"%select{method %5|constructor|destructor}4 "
"is %select{not deleted|deleted}6|"
"%select{method %5|constructor|destructor}4 "
+ "is %select{not defaulted|defaulted}6|"
+ "%select{method %5|constructor|destructor}4 "
"is %select{|pure }6%select{not virtual|virtual}7|"
"%select{method %5|constructor|destructor}4 "
"is %select{not static|static}6|"
@@ -211,6 +213,16 @@ def err_module_odr_violation_mismatch_decl_diff : Error<
"with %ordinal6 parameter with%select{out|}7 a default argument|"
"%select{method %5|constructor|destructor}4 "
"with %ordinal6 parameter with a default argument|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %select{no |}6template arguments|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %6 template argument%s6|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %6 for %ordinal7 template argument|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %select{no body|body}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "with body|"
"%select{typedef|type alias}4 name %5|"
"%select{typedef|type alias}4 %5 with underlying type %6|"
"data member with name %4|"
@@ -221,6 +233,18 @@ def err_module_odr_violation_mismatch_decl_diff : Error<
"friend %select{class|function}4|"
"friend %4|"
"friend function %4|"
+ "function template %4 with %5 template parameter%s5|"
+ "function template %4 with %ordinal5 template parameter being a "
+ "%select{type|non-type|template}6 template parameter|"
+ "function template %4 with %ordinal5 template parameter "
+ "%select{with no name|named %7}6|"
+ "function template %4 with %ordinal5 template parameter with "
+ "%select{no |}6default argument|"
+ "function template %4 with %ordinal5 template parameter with "
+ "default argument %6|"
+ "function template %4 with %ordinal5 template parameter with one type|"
+ "function template %4 with %ordinal5 template parameter %select{not |}6"
+ "being a template parameter pack|"
"}3">;
def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
@@ -239,6 +263,8 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
"%select{method %3|constructor|destructor}2 "
"is %select{not deleted|deleted}4|"
"%select{method %3|constructor|destructor}2 "
+ "is %select{not defaulted|defaulted}4|"
+ "%select{method %3|constructor|destructor}2 "
"is %select{|pure }4%select{not virtual|virtual}5|"
"%select{method %3|constructor|destructor}2 "
"is %select{not static|static}4|"
@@ -258,6 +284,16 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
"with %ordinal4 parameter with%select{out|}5 a default argument|"
"%select{method %3|constructor|destructor}2 "
"with %ordinal4 parameter with a different default argument|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %select{no |}4template arguments|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %4 template argument%s4|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %4 for %ordinal5 template argument|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %select{no body|body}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "with different body|"
"%select{typedef|type alias}2 name %3|"
"%select{typedef|type alias}2 %3 with different underlying type %4|"
"data member with name %2|"
@@ -268,6 +304,18 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
"friend %select{class|function}2|"
"friend %2|"
"friend function %2|"
+ "function template %2 with %3 template parameter%s3|"
+ "function template %2 with %ordinal3 template paramter being a "
+ "%select{type|non-type|template}4 template parameter|"
+ "function template %2 with %ordinal3 template parameter "
+ "%select{with no name|named %5}4|"
+ "function template %2 with %ordinal3 template parameter with "
+ "%select{no |}4default argument|"
+ "function template %2 with %ordinal3 template parameter with "
+ "default argument %4|"
+ "function template %2 with %ordinal3 template parameter with different type|"
+ "function template %2 with %ordinal3 template parameter %select{not |}4"
+ "being a template parameter pack|"
"}1">;
def err_module_odr_violation_function : Error<
@@ -293,6 +341,33 @@ def note_module_odr_violation_function : Note<"but in '%0' found "
"a different body"
"}1">;
+def err_module_odr_violation_enum : Error<
+ "%q0 has different definitions in different modules; "
+ "%select{definition in module '%2'|defined here}1 "
+ "first difference is "
+ "%select{"
+ "enum that is %select{not scoped|scoped}4|"
+ "enum scoped with keyword %select{struct|class}4|"
+ "enum %select{without|with}4 specified type|"
+ "enum with specified type %4|"
+ "enum with %4 element%s4|"
+ "%ordinal4 element has name %5|"
+ "%ordinal4 element %5 %select{has|does not have}6 an initilizer|"
+ "%ordinal4 element %5 has an initializer|"
+ "}3">;
+
+def note_module_odr_violation_enum : Note<"but in '%0' found "
+ "%select{"
+ "enum that is %select{not scoped|scoped}2|"
+ "enum scoped with keyword %select{struct|class}2|"
+ "enum %select{without|with}2 specified type|"
+ "enum with specified type %2|"
+ "enum with %2 element%s2|"
+ "%ordinal2 element has name %3|"
+ "%ordinal2 element %3 %select{has|does not have}4 an initializer|"
+ "%ordinal2 element %3 has different initializer|"
+ "}1">;
+
def err_module_odr_violation_mismatch_decl_unknown : Error<
"%q0 %select{with definition in module '%2'|defined here}1 has different "
"definitions in different modules; first difference is this "
diff --git a/include/clang/Basic/ExceptionSpecificationType.h b/include/clang/Basic/ExceptionSpecificationType.h
index 132b5ba1e5a79..0c2c8e6d860af 100644
--- a/include/clang/Basic/ExceptionSpecificationType.h
+++ b/include/clang/Basic/ExceptionSpecificationType.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the ExceptionSpecificationType enumeration and various
+/// Defines the ExceptionSpecificationType enumeration and various
/// utility functions.
///
//===----------------------------------------------------------------------===//
@@ -17,14 +17,16 @@
namespace clang {
-/// \brief The various types of exception specifications that exist in C++11.
+/// The various types of exception specifications that exist in C++11.
enum ExceptionSpecificationType {
EST_None, ///< no exception specification
EST_DynamicNone, ///< throw()
EST_Dynamic, ///< throw(T1, T2)
EST_MSAny, ///< Microsoft throw(...) extension
EST_BasicNoexcept, ///< noexcept
- EST_ComputedNoexcept, ///< noexcept(expression)
+ EST_DependentNoexcept,///< noexcept(expression), value-dependent
+ EST_NoexceptFalse, ///< noexcept(expression), evals to 'false'
+ EST_NoexceptTrue, ///< noexcept(expression), evals to 'true'
EST_Unevaluated, ///< not evaluated yet, for special member function
EST_Uninstantiated, ///< not instantiated yet
EST_Unparsed ///< not parsed yet
@@ -34,15 +36,20 @@ inline bool isDynamicExceptionSpec(ExceptionSpecificationType ESpecType) {
return ESpecType >= EST_DynamicNone && ESpecType <= EST_MSAny;
}
+inline bool isComputedNoexcept(ExceptionSpecificationType ESpecType) {
+ return ESpecType >= EST_DependentNoexcept &&
+ ESpecType <= EST_NoexceptTrue;
+}
+
inline bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType) {
- return ESpecType == EST_BasicNoexcept || ESpecType == EST_ComputedNoexcept;
+ return ESpecType == EST_BasicNoexcept || isComputedNoexcept(ESpecType);
}
inline bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType) {
return ESpecType == EST_Unevaluated || ESpecType == EST_Uninstantiated;
}
-/// \brief Possible results from evaluation of a noexcept expression.
+/// Possible results from evaluation of a noexcept expression.
enum CanThrowResult {
CT_Cannot,
CT_Dependent,
diff --git a/include/clang/Basic/ExpressionTraits.h b/include/clang/Basic/ExpressionTraits.h
index 0363a1d2c74c2..2983adde1ed65 100644
--- a/include/clang/Basic/ExpressionTraits.h
+++ b/include/clang/Basic/ExpressionTraits.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines enumerations for expression traits intrinsics.
+/// Defines enumerations for expression traits intrinsics.
///
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/Features.def b/include/clang/Basic/Features.def
new file mode 100644
index 0000000000000..a0e0ce4560abe
--- /dev/null
+++ b/include/clang/Basic/Features.def
@@ -0,0 +1,238 @@
+//===--- Features.def - Features and Extensions database --------*- 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 features exposed via __has_feature and extensions exposed
+// via __has_extension. Users of this file must either define the FEATURE or
+// EXTENSION macros (or both) to make use of this information. Note that these
+// macros expect the following declarations to be available for the Predicate:
+//
+// const LangOptions &LangOpts;
+// const Preprocessor &PP;
+//
+// The Predicate field dictates the conditions under which the feature or
+// extension will be made available.
+//===----------------------------------------------------------------------===//
+
+#if !defined(FEATURE) && !defined(EXTENSION)
+# error Define either the FEATURE or EXTENSION macro to handle features
+#endif
+
+#ifndef FEATURE
+#define FEATURE(Name, Predicate)
+#endif
+
+#ifndef EXTENSION
+#define EXTENSION(Name, Predicate)
+#endif
+
+FEATURE(address_sanitizer,
+ LangOpts.Sanitize.hasOneOf(SanitizerKind::Address |
+ SanitizerKind::KernelAddress))
+FEATURE(hwaddress_sanitizer,
+ LangOpts.Sanitize.hasOneOf(SanitizerKind::HWAddress |
+ SanitizerKind::KernelHWAddress))
+FEATURE(assume_nonnull, true)
+FEATURE(attribute_analyzer_noreturn, true)
+FEATURE(attribute_availability, true)
+FEATURE(attribute_availability_with_message, true)
+FEATURE(attribute_availability_app_extension, true)
+FEATURE(attribute_availability_with_version_underscores, true)
+FEATURE(attribute_availability_tvos, true)
+FEATURE(attribute_availability_watchos, true)
+FEATURE(attribute_availability_with_strict, true)
+FEATURE(attribute_availability_with_replacement, true)
+FEATURE(attribute_availability_in_templates, true)
+FEATURE(attribute_cf_returns_not_retained, true)
+FEATURE(attribute_cf_returns_retained, true)
+FEATURE(attribute_cf_returns_on_parameters, true)
+FEATURE(attribute_deprecated_with_message, true)
+FEATURE(attribute_deprecated_with_replacement, true)
+FEATURE(attribute_ext_vector_type, true)
+FEATURE(attribute_ns_returns_not_retained, true)
+FEATURE(attribute_ns_returns_retained, true)
+FEATURE(attribute_ns_consumes_self, true)
+FEATURE(attribute_ns_consumed, true)
+FEATURE(attribute_cf_consumed, true)
+FEATURE(attribute_objc_ivar_unused, true)
+FEATURE(attribute_objc_method_family, true)
+FEATURE(attribute_overloadable, true)
+FEATURE(attribute_unavailable_with_message, true)
+FEATURE(attribute_unused_on_fields, true)
+FEATURE(attribute_diagnose_if_objc, true)
+FEATURE(blocks, LangOpts.Blocks)
+FEATURE(c_thread_safety_attributes, true)
+FEATURE(cxx_exceptions, LangOpts.CXXExceptions)
+FEATURE(cxx_rtti, LangOpts.RTTI &&LangOpts.RTTIData)
+FEATURE(enumerator_attributes, true)
+FEATURE(nullability, true)
+FEATURE(nullability_on_arrays, true)
+FEATURE(memory_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Memory))
+FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread))
+FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
+FEATURE(efficiency_sanitizer,
+ LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency))
+FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
+// Objective-C features
+FEATURE(objc_arr, LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
+FEATURE(objc_arc, LangOpts.ObjCAutoRefCount)
+FEATURE(objc_arc_fields, true)
+FEATURE(objc_arc_weak, LangOpts.ObjCWeak)
+FEATURE(objc_default_synthesize_properties, LangOpts.ObjC2)
+FEATURE(objc_fixed_enum, LangOpts.ObjC2)
+FEATURE(objc_instancetype, LangOpts.ObjC2)
+FEATURE(objc_kindof, LangOpts.ObjC2)
+FEATURE(objc_modules, LangOpts.ObjC2 &&LangOpts.Modules)
+FEATURE(objc_nonfragile_abi, LangOpts.ObjCRuntime.isNonFragile())
+FEATURE(objc_property_explicit_atomic, true)
+FEATURE(objc_protocol_qualifier_mangling, true)
+FEATURE(objc_weak_class, LangOpts.ObjCRuntime.hasWeakClassImport())
+FEATURE(ownership_holds, true)
+FEATURE(ownership_returns, true)
+FEATURE(ownership_takes, true)
+FEATURE(objc_bool, true)
+FEATURE(objc_subscripting, LangOpts.ObjCRuntime.isNonFragile())
+FEATURE(objc_array_literals, LangOpts.ObjC2)
+FEATURE(objc_dictionary_literals, LangOpts.ObjC2)
+FEATURE(objc_boxed_expressions, LangOpts.ObjC2)
+FEATURE(objc_boxed_nsvalue_expressions, LangOpts.ObjC2)
+FEATURE(arc_cf_code_audited, true)
+FEATURE(objc_bridge_id, true)
+FEATURE(objc_bridge_id_on_typedefs, true)
+FEATURE(objc_generics, LangOpts.ObjC2)
+FEATURE(objc_generics_variance, LangOpts.ObjC2)
+FEATURE(objc_class_property, LangOpts.ObjC2)
+// C11 features
+FEATURE(c_alignas, LangOpts.C11)
+FEATURE(c_alignof, LangOpts.C11)
+FEATURE(c_atomic, LangOpts.C11)
+FEATURE(c_generic_selections, LangOpts.C11)
+FEATURE(c_static_assert, LangOpts.C11)
+FEATURE(c_thread_local, LangOpts.C11 &&PP.getTargetInfo().isTLSSupported())
+// C++11 features
+FEATURE(cxx_access_control_sfinae, LangOpts.CPlusPlus11)
+FEATURE(cxx_alias_templates, LangOpts.CPlusPlus11)
+FEATURE(cxx_alignas, LangOpts.CPlusPlus11)
+FEATURE(cxx_alignof, LangOpts.CPlusPlus11)
+FEATURE(cxx_atomic, LangOpts.CPlusPlus11)
+FEATURE(cxx_attributes, LangOpts.CPlusPlus11)
+FEATURE(cxx_auto_type, LangOpts.CPlusPlus11)
+FEATURE(cxx_constexpr, LangOpts.CPlusPlus11)
+FEATURE(cxx_constexpr_string_builtins, LangOpts.CPlusPlus11)
+FEATURE(cxx_decltype, LangOpts.CPlusPlus11)
+FEATURE(cxx_decltype_incomplete_return_types, LangOpts.CPlusPlus11)
+FEATURE(cxx_default_function_template_args, LangOpts.CPlusPlus11)
+FEATURE(cxx_defaulted_functions, LangOpts.CPlusPlus11)
+FEATURE(cxx_delegating_constructors, LangOpts.CPlusPlus11)
+FEATURE(cxx_deleted_functions, LangOpts.CPlusPlus11)
+FEATURE(cxx_explicit_conversions, LangOpts.CPlusPlus11)
+FEATURE(cxx_generalized_initializers, LangOpts.CPlusPlus11)
+FEATURE(cxx_implicit_moves, LangOpts.CPlusPlus11)
+FEATURE(cxx_inheriting_constructors, LangOpts.CPlusPlus11)
+FEATURE(cxx_inline_namespaces, LangOpts.CPlusPlus11)
+FEATURE(cxx_lambdas, LangOpts.CPlusPlus11)
+FEATURE(cxx_local_type_template_args, LangOpts.CPlusPlus11)
+FEATURE(cxx_nonstatic_member_init, LangOpts.CPlusPlus11)
+FEATURE(cxx_noexcept, LangOpts.CPlusPlus11)
+FEATURE(cxx_nullptr, LangOpts.CPlusPlus11)
+FEATURE(cxx_override_control, LangOpts.CPlusPlus11)
+FEATURE(cxx_range_for, LangOpts.CPlusPlus11)
+FEATURE(cxx_raw_string_literals, LangOpts.CPlusPlus11)
+FEATURE(cxx_reference_qualified_functions, LangOpts.CPlusPlus11)
+FEATURE(cxx_rvalue_references, LangOpts.CPlusPlus11)
+FEATURE(cxx_strong_enums, LangOpts.CPlusPlus11)
+FEATURE(cxx_static_assert, LangOpts.CPlusPlus11)
+FEATURE(cxx_thread_local,
+ LangOpts.CPlusPlus11 &&PP.getTargetInfo().isTLSSupported())
+FEATURE(cxx_trailing_return, LangOpts.CPlusPlus11)
+FEATURE(cxx_unicode_literals, LangOpts.CPlusPlus11)
+FEATURE(cxx_unrestricted_unions, LangOpts.CPlusPlus11)
+FEATURE(cxx_user_literals, LangOpts.CPlusPlus11)
+FEATURE(cxx_variadic_templates, LangOpts.CPlusPlus11)
+// C++14 features
+FEATURE(cxx_aggregate_nsdmi, LangOpts.CPlusPlus14)
+FEATURE(cxx_binary_literals, LangOpts.CPlusPlus14)
+FEATURE(cxx_contextual_conversions, LangOpts.CPlusPlus14)
+FEATURE(cxx_decltype_auto, LangOpts.CPlusPlus14)
+FEATURE(cxx_generic_lambdas, LangOpts.CPlusPlus14)
+FEATURE(cxx_init_captures, LangOpts.CPlusPlus14)
+FEATURE(cxx_relaxed_constexpr, LangOpts.CPlusPlus14)
+FEATURE(cxx_return_type_deduction, LangOpts.CPlusPlus14)
+FEATURE(cxx_variable_templates, LangOpts.CPlusPlus14)
+// NOTE: For features covered by SD-6, it is preferable to provide *only*
+// the SD-6 macro and not a __has_feature check.
+
+// C++ TSes
+// FEATURE(cxx_runtime_arrays, LangOpts.CPlusPlusTSArrays)
+// FEATURE(cxx_concepts, LangOpts.CPlusPlusTSConcepts)
+// FIXME: Should this be __has_feature or __has_extension?
+// FEATURE(raw_invocation_type, LangOpts.CPlusPlus)
+// Type traits
+// N.B. Additional type traits should not be added to the following list.
+// Instead, they should be detected by has_extension.
+FEATURE(has_nothrow_assign, LangOpts.CPlusPlus)
+FEATURE(has_nothrow_copy, LangOpts.CPlusPlus)
+FEATURE(has_nothrow_constructor, LangOpts.CPlusPlus)
+FEATURE(has_trivial_assign, LangOpts.CPlusPlus)
+FEATURE(has_trivial_copy, LangOpts.CPlusPlus)
+FEATURE(has_trivial_constructor, LangOpts.CPlusPlus)
+FEATURE(has_trivial_destructor, LangOpts.CPlusPlus)
+FEATURE(has_virtual_destructor, LangOpts.CPlusPlus)
+FEATURE(is_abstract, LangOpts.CPlusPlus)
+FEATURE(is_base_of, LangOpts.CPlusPlus)
+FEATURE(is_class, LangOpts.CPlusPlus)
+FEATURE(is_constructible, LangOpts.CPlusPlus)
+FEATURE(is_convertible_to, LangOpts.CPlusPlus)
+FEATURE(is_empty, LangOpts.CPlusPlus)
+FEATURE(is_enum, LangOpts.CPlusPlus)
+FEATURE(is_final, LangOpts.CPlusPlus)
+FEATURE(is_literal, LangOpts.CPlusPlus)
+FEATURE(is_standard_layout, LangOpts.CPlusPlus)
+FEATURE(is_pod, LangOpts.CPlusPlus)
+FEATURE(is_polymorphic, LangOpts.CPlusPlus)
+FEATURE(is_sealed, LangOpts.CPlusPlus &&LangOpts.MicrosoftExt)
+FEATURE(is_trivial, LangOpts.CPlusPlus)
+FEATURE(is_trivially_assignable, LangOpts.CPlusPlus)
+FEATURE(is_trivially_constructible, LangOpts.CPlusPlus)
+FEATURE(is_trivially_copyable, LangOpts.CPlusPlus)
+FEATURE(is_union, LangOpts.CPlusPlus)
+FEATURE(modules, LangOpts.Modules)
+FEATURE(safe_stack, LangOpts.Sanitize.has(SanitizerKind::SafeStack))
+FEATURE(shadow_call_stack,
+ LangOpts.Sanitize.has(SanitizerKind::ShadowCallStack))
+FEATURE(tls, PP.getTargetInfo().isTLSSupported())
+FEATURE(underlying_type, LangOpts.CPlusPlus)
+
+// C11 features supported by other languages as extensions.
+EXTENSION(c_alignas, true)
+EXTENSION(c_alignof, true)
+EXTENSION(c_atomic, true)
+EXTENSION(c_generic_selections, true)
+EXTENSION(c_static_assert, true)
+EXTENSION(c_thread_local, PP.getTargetInfo().isTLSSupported())
+// C++11 features supported by other languages as extensions.
+EXTENSION(cxx_atomic, LangOpts.CPlusPlus)
+EXTENSION(cxx_deleted_functions, LangOpts.CPlusPlus)
+EXTENSION(cxx_explicit_conversions, LangOpts.CPlusPlus)
+EXTENSION(cxx_inline_namespaces, LangOpts.CPlusPlus)
+EXTENSION(cxx_local_type_template_args, LangOpts.CPlusPlus)
+EXTENSION(cxx_nonstatic_member_init, LangOpts.CPlusPlus)
+EXTENSION(cxx_override_control, LangOpts.CPlusPlus)
+EXTENSION(cxx_range_for, LangOpts.CPlusPlus)
+EXTENSION(cxx_reference_qualified_functions, LangOpts.CPlusPlus)
+EXTENSION(cxx_rvalue_references, LangOpts.CPlusPlus)
+EXTENSION(cxx_variadic_templates, LangOpts.CPlusPlus)
+// C++14 features supported by other languages as extensions.
+EXTENSION(cxx_binary_literals, true)
+EXTENSION(cxx_init_captures, LangOpts.CPlusPlus11)
+EXTENSION(cxx_variable_templates, LangOpts.CPlusPlus)
+// Miscellaneous language extensions
+EXTENSION(overloadable_unmarked, true)
+
+#undef EXTENSION
+#undef FEATURE
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index b817dd20c3013..ab5dfca716397 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the clang::FileManager interface and associated types.
+/// Defines the clang::FileManager interface and associated types.
///
//===----------------------------------------------------------------------===//
@@ -40,7 +40,7 @@ namespace clang {
class FileSystemStatCache;
-/// \brief Cached information about one directory (either on disk or in
+/// Cached information about one directory (either on disk or in
/// the virtual file system).
class DirectoryEntry {
friend class FileManager;
@@ -51,7 +51,7 @@ public:
StringRef getName() const { return Name; }
};
-/// \brief Cached information about one file (either on disk
+/// Cached information about one file (either on disk
/// or in the virtual file system).
///
/// If the 'File' member is valid, then this FileEntry has an open file
@@ -70,7 +70,7 @@ class FileEntry {
bool InPCH;
bool IsValid; // Is this \c FileEntry initialized and valid?
- /// \brief The open file, if it is owned by the \p FileEntry.
+ /// The open file, if it is owned by the \p FileEntry.
mutable std::unique_ptr<vfs::File> File;
public:
@@ -90,12 +90,12 @@ public:
bool isInPCH() const { return InPCH; }
time_t getModificationTime() const { return ModTime; }
- /// \brief Return the directory the file lives in.
+ /// Return the directory the file lives in.
const DirectoryEntry *getDir() const { return Dir; }
bool operator<(const FileEntry &RHS) const { return UniqueID < RHS.UniqueID; }
- /// \brief Check whether the file is a named pipe (and thus can't be opened by
+ /// Check whether the file is a named pipe (and thus can't be opened by
/// the native FileManager methods).
bool isNamedPipe() const { return IsNamedPipe; }
@@ -106,7 +106,7 @@ public:
struct FileData;
-/// \brief Implements support for file system lookup, file system caching,
+/// Implements support for file system lookup, file system caching,
/// and directory search management.
///
/// This also handles more advanced properties, such as uniquing files based
@@ -117,21 +117,21 @@ class FileManager : public RefCountedBase<FileManager> {
IntrusiveRefCntPtr<vfs::FileSystem> FS;
FileSystemOptions FileSystemOpts;
- /// \brief Cache for existing real directories.
+ /// Cache for existing real directories.
std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueRealDirs;
- /// \brief Cache for existing real files.
+ /// Cache for existing real files.
std::map<llvm::sys::fs::UniqueID, FileEntry> UniqueRealFiles;
- /// \brief The virtual directories that we have allocated.
+ /// The virtual directories that we have allocated.
///
/// For each virtual file (e.g. foo/bar/baz.cpp), we add all of its parent
/// directories (foo/ and foo/bar/) here.
SmallVector<std::unique_ptr<DirectoryEntry>, 4> VirtualDirectoryEntries;
- /// \brief The virtual files that we have allocated.
+ /// The virtual files that we have allocated.
SmallVector<std::unique_ptr<FileEntry>, 4> VirtualFileEntries;
- /// \brief A cache that maps paths to directory entries (either real or
+ /// A cache that maps paths to directory entries (either real or
/// virtual) we have looked up
///
/// The actual Entries for real directories/files are
@@ -141,19 +141,19 @@ class FileManager : public RefCountedBase<FileManager> {
///
llvm::StringMap<DirectoryEntry*, llvm::BumpPtrAllocator> SeenDirEntries;
- /// \brief A cache that maps paths to file entries (either real or
+ /// A cache that maps paths to file entries (either real or
/// virtual) we have looked up.
///
/// \see SeenDirEntries
llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator> SeenFileEntries;
- /// \brief The canonical names of directories.
+ /// The canonical names of directories.
llvm::DenseMap<const DirectoryEntry *, llvm::StringRef> CanonicalDirNames;
- /// \brief Storage for canonical names that we have computed.
+ /// Storage for canonical names that we have computed.
llvm::BumpPtrAllocator CanonicalNameStorage;
- /// \brief Each FileEntry we create is assigned a unique ID #.
+ /// Each FileEntry we create is assigned a unique ID #.
///
unsigned NextFileUID;
@@ -176,7 +176,7 @@ public:
IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
~FileManager();
- /// \brief Installs the provided FileSystemStatCache object within
+ /// Installs the provided FileSystemStatCache object within
/// the FileManager.
///
/// Ownership of this object is transferred to the FileManager.
@@ -190,13 +190,13 @@ public:
void addStatCache(std::unique_ptr<FileSystemStatCache> statCache,
bool AtBeginning = false);
- /// \brief Removes the specified FileSystemStatCache object from the manager.
+ /// Removes the specified FileSystemStatCache object from the manager.
void removeStatCache(FileSystemStatCache *statCache);
- /// \brief Removes all FileSystemStatCache objects from the manager.
+ /// Removes all FileSystemStatCache objects from the manager.
void clearStatCaches();
- /// \brief Lookup, cache, and verify the specified directory (real or
+ /// Lookup, cache, and verify the specified directory (real or
/// virtual).
///
/// This returns NULL if the directory doesn't exist.
@@ -206,7 +206,7 @@ public:
const DirectoryEntry *getDirectory(StringRef DirName,
bool CacheFailure = true);
- /// \brief Lookup, cache, and verify the specified file (real or
+ /// Lookup, cache, and verify the specified file (real or
/// virtual).
///
/// This returns NULL if the file doesn't exist.
@@ -218,7 +218,7 @@ public:
const FileEntry *getFile(StringRef Filename, bool OpenFile = false,
bool CacheFailure = true);
- /// \brief Returns the current file system options
+ /// Returns the current file system options
FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
@@ -226,22 +226,22 @@ public:
return FS;
}
- /// \brief Retrieve a file entry for a "virtual" file that acts as
+ /// Retrieve a file entry for a "virtual" file that acts as
/// if there were a file with the given name on disk.
///
/// The file itself is not accessed.
const FileEntry *getVirtualFile(StringRef Filename, off_t Size,
time_t ModificationTime);
- /// \brief Open the specified file as a MemoryBuffer, returning a new
+ /// Open the specified file as a MemoryBuffer, returning a new
/// MemoryBuffer if successful, otherwise returning null.
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBufferForFile(const FileEntry *Entry, bool isVolatile = false,
bool ShouldCloseOpenFile = true);
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
- getBufferForFile(StringRef Filename);
+ getBufferForFile(StringRef Filename, bool isVolatile = false);
- /// \brief Get the 'stat' information for the given \p Path.
+ /// Get the 'stat' information for the given \p Path.
///
/// If the path is relative, it will be resolved against the WorkingDir of the
/// FileManager's FileSystemOptions.
@@ -250,10 +250,10 @@ public:
bool getNoncachedStatValue(StringRef Path,
vfs::Status &Result);
- /// \brief Remove the real file \p Entry from the cache.
+ /// Remove the real file \p Entry from the cache.
void invalidateCache(const FileEntry *Entry);
- /// \brief If path is not absolute and FileSystemOptions set the working
+ /// If path is not absolute and FileSystemOptions set the working
/// directory, the path is modified to be relative to the given
/// working directory.
/// \returns true if \c path changed.
@@ -264,17 +264,17 @@ public:
/// \returns true if \c Path changed to absolute.
bool makeAbsolutePath(SmallVectorImpl<char> &Path) const;
- /// \brief Produce an array mapping from the unique IDs assigned to each
+ /// Produce an array mapping from the unique IDs assigned to each
/// file to the corresponding FileEntry pointer.
void GetUniqueIDMapping(
SmallVectorImpl<const FileEntry *> &UIDToFiles) const;
- /// \brief Modifies the size and modification time of a previously created
+ /// Modifies the size and modification time of a previously created
/// FileEntry. Use with caution.
static void modifyFileEntry(FileEntry *File, off_t Size,
time_t ModificationTime);
- /// \brief Retrieve the canonical name for a given directory.
+ /// Retrieve the canonical name for a given directory.
///
/// This is a very expensive operation, despite its results being cached,
/// and should only be used when the physical layout of the file system is
diff --git a/include/clang/Basic/FileSystemOptions.h b/include/clang/Basic/FileSystemOptions.h
index 38f1346312489..8b8b13bb56869 100644
--- a/include/clang/Basic/FileSystemOptions.h
+++ b/include/clang/Basic/FileSystemOptions.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the clang::FileSystemOptions interface.
+/// Defines the clang::FileSystemOptions interface.
///
//===----------------------------------------------------------------------===//
@@ -19,10 +19,10 @@
namespace clang {
-/// \brief Keeps track of options that affect how file operations are performed.
+/// Keeps track of options that affect how file operations are performed.
class FileSystemOptions {
public:
- /// \brief If set, paths are resolved as if the working directory was
+ /// If set, paths are resolved as if the working directory was
/// set to the value of WorkingDir.
std::string WorkingDir;
};
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
index 75f986b59bddc..45aded527c1bd 100644
--- a/include/clang/Basic/FileSystemStatCache.h
+++ b/include/clang/Basic/FileSystemStatCache.h
@@ -1,4 +1,4 @@
-//===--- FileSystemStatCache.h - Caching for 'stat' calls -------*- C++ -*-===//
+//===- FileSystemStatCache.h - Caching for 'stat' calls ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
-/// \brief Defines the FileSystemStatCache interface.
-///
+/// Defines the FileSystemStatCache interface.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H
@@ -17,48 +17,61 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/FileSystem.h"
+#include <cstdint>
+#include <ctime>
#include <memory>
+#include <string>
+#include <utility>
namespace clang {
namespace vfs {
+
class File;
class FileSystem;
-}
+
+} // namespace vfs
// FIXME: should probably replace this with vfs::Status
struct FileData {
std::string Name;
- uint64_t Size;
- time_t ModTime;
+ uint64_t Size = 0;
+ time_t ModTime = 0;
llvm::sys::fs::UniqueID UniqueID;
- bool IsDirectory;
- bool IsNamedPipe;
- bool InPCH;
- bool IsVFSMapped; // FIXME: remove this when files support multiple names
- FileData()
- : Size(0), ModTime(0), IsDirectory(false), IsNamedPipe(false),
- InPCH(false), IsVFSMapped(false) {}
+ bool IsDirectory = false;
+ bool IsNamedPipe = false;
+ bool InPCH = false;
+
+ // FIXME: remove this when files support multiple names
+ bool IsVFSMapped = false;
+
+ FileData() = default;
};
-/// \brief Abstract interface for introducing a FileManager cache for 'stat'
+/// Abstract interface for introducing a FileManager cache for 'stat'
/// system calls, which is used by precompiled and pretokenized headers to
/// improve performance.
class FileSystemStatCache {
virtual void anchor();
+
protected:
std::unique_ptr<FileSystemStatCache> NextStatCache;
public:
- virtual ~FileSystemStatCache() {}
+ virtual ~FileSystemStatCache() = default;
enum LookupResult {
- CacheExists, ///< We know the file exists and its cached stat data.
- CacheMissing ///< We know that the file doesn't exist.
+ /// We know the file exists and its cached stat data.
+ CacheExists,
+
+ /// We know that the file doesn't exist.
+ CacheMissing
};
- /// \brief Get the 'stat' information for the specified path, using the cache
+ /// Get the 'stat' information for the specified path, using the cache
/// to accelerate it if possible.
///
/// \returns \c true if the path does not exist or \c false if it exists.
@@ -72,16 +85,16 @@ public:
std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache,
vfs::FileSystem &FS);
- /// \brief Sets the next stat call cache in the chain of stat caches.
+ /// Sets the next stat call cache in the chain of stat caches.
/// Takes ownership of the given stat cache.
void setNextStatCache(std::unique_ptr<FileSystemStatCache> Cache) {
NextStatCache = std::move(Cache);
}
- /// \brief Retrieve the next stat call cache in the chain.
+ /// Retrieve the next stat call cache in the chain.
FileSystemStatCache *getNextStatCache() { return NextStatCache.get(); }
- /// \brief Retrieve the next stat call cache in the chain, transferring
+ /// Retrieve the next stat call cache in the chain, transferring
/// ownership of this cache (and, transitively, all of the remaining caches)
/// to the caller.
std::unique_ptr<FileSystemStatCache> takeNextStatCache() {
@@ -107,16 +120,16 @@ protected:
}
};
-/// \brief A stat "cache" that can be used by FileManager to keep
+/// A stat "cache" that can be used by FileManager to keep
/// track of the results of stat() calls that occur throughout the
/// execution of the front end.
class MemorizeStatCalls : public FileSystemStatCache {
public:
- /// \brief The set of stat() calls that have been seen.
+ /// The set of stat() calls that have been seen.
llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls;
- typedef llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator
- iterator;
+ using iterator =
+ llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator;
iterator begin() const { return StatCalls.begin(); }
iterator end() const { return StatCalls.end(); }
@@ -126,6 +139,6 @@ public:
vfs::FileSystem &FS) override;
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_BASIC_FILESYSTEMSTATCACHE_H
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 8e3c15afbfcd4..f43df5c64829d 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Defines the clang::IdentifierInfo, clang::IdentifierTable, and
+/// Defines the clang::IdentifierInfo, clang::IdentifierTable, and
/// clang::Selector interfaces.
//
//===----------------------------------------------------------------------===//
@@ -39,7 +39,7 @@ class LangOptions;
class MultiKeywordSelector;
class SourceLocation;
-/// \brief A simple pair of identifier info and location.
+/// A simple pair of identifier info and location.
using IdentifierLocPair = std::pair<IdentifierInfo *, SourceLocation>;
/// One of these records is kept for each identifier that
@@ -89,7 +89,7 @@ public:
IdentifierInfo(const IdentifierInfo &) = delete;
IdentifierInfo &operator=(const IdentifierInfo &) = delete;
- /// \brief Return true if this is the identifier for the specified string.
+ /// Return true if this is the identifier for the specified string.
///
/// This is intended to be used for string literals only: II->isStr("foo").
template <std::size_t StrLen>
@@ -98,7 +98,13 @@ public:
memcmp(getNameStart(), Str, StrLen-1) == 0;
}
- /// \brief Return the beginning of the actual null-terminated string for this
+ /// Return true if this is the identifier for the specified StringRef.
+ bool isStr(llvm::StringRef Str) const {
+ llvm::StringRef ThisStr(getNameStart(), getLength());
+ return ThisStr == Str;
+ }
+
+ /// Return the beginning of the actual null-terminated string for this
/// identifier.
const char *getNameStart() const {
if (Entry) return Entry->getKeyData();
@@ -112,7 +118,7 @@ public:
return ((const actualtype*) this)->second;
}
- /// \brief Efficiently return the length of this identifier info.
+ /// Efficiently return the length of this identifier info.
unsigned getLength() const {
if (Entry) return Entry->getKeyLength();
// FIXME: This is gross. It would be best not to embed specific details
@@ -126,12 +132,12 @@ public:
return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
}
- /// \brief Return the actual identifier string.
+ /// Return the actual identifier string.
StringRef getName() const {
return StringRef(getNameStart(), getLength());
}
- /// \brief Return true if this identifier is \#defined to some other value.
+ /// Return true if this identifier is \#defined to some other value.
/// \note The current definition may be in a module and not currently visible.
bool hasMacroDefinition() const {
return HasMacro;
@@ -147,7 +153,7 @@ public:
RecomputeNeedsHandleIdentifier();
}
}
- /// \brief Returns true if this identifier was \#defined to some value at any
+ /// Returns true if this identifier was \#defined to some value at any
/// moment. In this case there should be an entry for the identifier in the
/// macro history table in Preprocessor.
bool hadMacroDefinition() const {
@@ -159,10 +165,10 @@ public:
/// tokens.
tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
- /// \brief True if revertTokenIDToIdentifier() was called.
+ /// True if revertTokenIDToIdentifier() was called.
bool hasRevertedTokenIDToIdentifier() const { return RevertedTokenID; }
- /// \brief Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2
+ /// Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2
/// compatibility.
///
/// TokenID is normally read-only but there are 2 instances where we revert it
@@ -179,12 +185,12 @@ public:
RevertedTokenID = false;
}
- /// \brief Return the preprocessor keyword ID for this identifier.
+ /// Return the preprocessor keyword ID for this identifier.
///
/// For example, "define" will return tok::pp_define.
tok::PPKeywordKind getPPKeywordID() const;
- /// \brief Return the Objective-C keyword ID for the this identifier.
+ /// Return the Objective-C keyword ID for the this identifier.
///
/// For example, 'class' will return tok::objc_class if ObjC is enabled.
tok::ObjCKeywordKind getObjCKeywordID() const {
@@ -195,19 +201,19 @@ public:
}
void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
- /// \brief True if setNotBuiltin() was called.
+ /// True if setNotBuiltin() was called.
bool hasRevertedBuiltin() const {
return ObjCOrBuiltinID == tok::NUM_OBJC_KEYWORDS;
}
- /// \brief Revert the identifier to a non-builtin identifier. We do this if
+ /// Revert the identifier to a non-builtin identifier. We do this if
/// the name of a known builtin library function is used to declare that
/// function, but an unexpected type is specified.
void revertBuiltin() {
setBuiltinID(0);
}
- /// \brief Return a value indicating whether this is a builtin function.
+ /// Return a value indicating whether this is a builtin function.
///
/// 0 is not-built-in. 1+ are specific builtin functions.
unsigned getBuiltinID() const {
@@ -261,7 +267,7 @@ public:
RecomputeNeedsHandleIdentifier();
}
- /// \brief Return true if this token has been poisoned.
+ /// Return true if this token has been poisoned.
bool isPoisoned() const { return IsPoisoned; }
/// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
@@ -271,10 +277,10 @@ public:
}
bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
- /// \brief Return true if this token is a keyword in the specified language.
+ /// Return true if this token is a keyword in the specified language.
bool isKeyword(const LangOptions &LangOpts) const;
- /// \brief Return true if this token is a C++ keyword in the specified
+ /// Return true if this token is a C++ keyword in the specified
/// language.
bool isCPlusPlusKeyword(const LangOptions &LangOpts) const;
@@ -284,48 +290,48 @@ public:
T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
void setFETokenInfo(void *T) { FETokenInfo = T; }
- /// \brief Return true if the Preprocessor::HandleIdentifier must be called
+ /// Return true if the Preprocessor::HandleIdentifier must be called
/// on a token of this identifier.
///
/// If this returns false, we know that HandleIdentifier will not affect
/// the token.
bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; }
- /// \brief Return true if the identifier in its current state was loaded
+ /// Return true if the identifier in its current state was loaded
/// from an AST file.
bool isFromAST() const { return IsFromAST; }
void setIsFromAST() { IsFromAST = true; }
- /// \brief Determine whether this identifier has changed since it was loaded
+ /// Determine whether this identifier has changed since it was loaded
/// from an AST file.
bool hasChangedSinceDeserialization() const {
return ChangedAfterLoad;
}
- /// \brief Note that this identifier has changed since it was loaded from
+ /// Note that this identifier has changed since it was loaded from
/// an AST file.
void setChangedSinceDeserialization() {
ChangedAfterLoad = true;
}
- /// \brief Determine whether the frontend token information for this
+ /// Determine whether the frontend token information for this
/// identifier has changed since it was loaded from an AST file.
bool hasFETokenInfoChangedSinceDeserialization() const {
return FEChangedAfterLoad;
}
- /// \brief Note that the frontend token information for this identifier has
+ /// Note that the frontend token information for this identifier has
/// changed since it was loaded from an AST file.
void setFETokenInfoChangedSinceDeserialization() {
FEChangedAfterLoad = true;
}
- /// \brief Determine whether the information for this identifier is out of
+ /// Determine whether the information for this identifier is out of
/// date with respect to the external source.
bool isOutOfDate() const { return OutOfDate; }
- /// \brief Set whether the information for this identifier is out of
+ /// Set whether the information for this identifier is out of
/// date with respect to the external source.
void setOutOfDate(bool OOD) {
OutOfDate = OOD;
@@ -335,10 +341,10 @@ public:
RecomputeNeedsHandleIdentifier();
}
- /// \brief Determine whether this is the contextual keyword \c import.
+ /// Determine whether this is the contextual keyword \c import.
bool isModulesImport() const { return IsModulesImport; }
- /// \brief Set whether this identifier is the contextual keyword \c import.
+ /// Set whether this identifier is the contextual keyword \c import.
void setModulesImport(bool I) {
IsModulesImport = I;
if (I)
@@ -360,7 +366,7 @@ public:
return getName().startswith("<#") && getName().endswith("#>");
}
- /// \brief Provide less than operator for lexicographical sorting.
+ /// Provide less than operator for lexicographical sorting.
bool operator<(const IdentifierInfo &RHS) const {
return getName() < RHS.getName();
}
@@ -379,7 +385,7 @@ private:
}
};
-/// \brief An RAII object for [un]poisoning an identifier within a scope.
+/// An RAII object for [un]poisoning an identifier within a scope.
///
/// \p II is allowed to be null, in which case objects of this type have
/// no effect.
@@ -400,7 +406,7 @@ public:
}
};
-/// \brief An iterator that walks over all of the known identifiers
+/// An iterator that walks over all of the known identifiers
/// in the lookup table.
///
/// Since this iterator uses an abstract interface via virtual
@@ -420,7 +426,7 @@ public:
virtual ~IdentifierIterator();
- /// \brief Retrieve the next string in the identifier table and
+ /// Retrieve the next string in the identifier table and
/// advances the iterator for the following string.
///
/// \returns The next string in the identifier table. If there is
@@ -428,19 +434,19 @@ public:
virtual StringRef Next() = 0;
};
-/// \brief Provides lookups to, and iteration over, IdentiferInfo objects.
+/// Provides lookups to, and iteration over, IdentiferInfo objects.
class IdentifierInfoLookup {
public:
virtual ~IdentifierInfoLookup();
- /// \brief Return the IdentifierInfo for the specified named identifier.
+ /// Return the IdentifierInfo for the specified named identifier.
///
/// Unlike the version in IdentifierTable, this returns a pointer instead
/// of a reference. If the pointer is null then the IdentifierInfo cannot
/// be found.
virtual IdentifierInfo* get(StringRef Name) = 0;
- /// \brief Retrieve an iterator into the set of all identifiers
+ /// Retrieve an iterator into the set of all identifiers
/// known to this identifier lookup source.
///
/// This routine provides access to all of the identifiers known to
@@ -453,7 +459,7 @@ public:
virtual IdentifierIterator *getIdentifiers();
};
-/// \brief Implements an efficient mapping from strings to IdentifierInfo nodes.
+/// Implements an efficient mapping from strings to IdentifierInfo nodes.
///
/// This has no other purpose, but this is an extremely performance-critical
/// piece of the code, as each occurrence of every identifier goes through
@@ -467,17 +473,20 @@ class IdentifierTable {
IdentifierInfoLookup* ExternalLookup;
public:
- /// \brief Create the identifier table, populating it with info about the
+ /// Create the identifier table.
+ explicit IdentifierTable(IdentifierInfoLookup *ExternalLookup = nullptr);
+
+ /// Create the identifier table, populating it with info about the
/// language keywords for the language specified by \p LangOpts.
- IdentifierTable(const LangOptions &LangOpts,
- IdentifierInfoLookup* externalLookup = nullptr);
+ explicit IdentifierTable(const LangOptions &LangOpts,
+ IdentifierInfoLookup *ExternalLookup = nullptr);
- /// \brief Set the external identifier lookup mechanism.
+ /// Set the external identifier lookup mechanism.
void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
ExternalLookup = IILookup;
}
- /// \brief Retrieve the external identifier lookup object, if any.
+ /// Retrieve the external identifier lookup object, if any.
IdentifierInfoLookup *getExternalIdentifierLookup() const {
return ExternalLookup;
}
@@ -486,7 +495,7 @@ public:
return HashTable.getAllocator();
}
- /// \brief Return the identifier token info for the specified named
+ /// Return the identifier token info for the specified named
/// identifier.
IdentifierInfo &get(StringRef Name) {
auto &Entry = *HashTable.insert(std::make_pair(Name, nullptr)).first;
@@ -519,7 +528,7 @@ public:
return II;
}
- /// \brief Gets an IdentifierInfo for the given name without consulting
+ /// Gets an IdentifierInfo for the given name without consulting
/// external sources.
///
/// This is a version of get() meant for external sources that want to
@@ -554,14 +563,16 @@ public:
iterator end() const { return HashTable.end(); }
unsigned size() const { return HashTable.size(); }
- /// \brief Print some statistics to stderr that indicate how well the
+ /// Print some statistics to stderr that indicate how well the
/// hashing is doing.
void PrintStats() const;
+ /// Populate the identifier table with info about the language keywords
+ /// for the language specified by \p LangOpts.
void AddKeywords(const LangOptions &LangOpts);
};
-/// \brief A family of Objective-C methods.
+/// A family of Objective-C methods.
///
/// These families have no inherent meaning in the language, but are
/// nonetheless central enough in the existing implementations to
@@ -579,7 +590,7 @@ public:
/// explicitly change or remove a method's family. Therefore the
/// method's family should be considered the single source of truth.
enum ObjCMethodFamily {
- /// \brief No particular method family.
+ /// No particular method family.
OMF_None,
// Selectors in these families may have arbitrary arity, may be
@@ -611,10 +622,10 @@ enum ObjCMethodFamily {
/// InvalidObjCMethodFamily.
enum { ObjCMethodFamilyBitWidth = 4 };
-/// \brief An invalid value of ObjCMethodFamily.
+/// An invalid value of ObjCMethodFamily.
enum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 };
-/// \brief A family of Objective-C methods.
+/// A family of Objective-C methods.
///
/// These are family of methods whose result type is initially 'id', but
/// but are candidate for the result type to be changed to 'instancetype'.
@@ -633,7 +644,7 @@ enum ObjCStringFormatFamily {
SFF_CFString
};
-/// \brief Smart pointer class that efficiently represents Objective-C method
+/// Smart pointer class that efficiently represents Objective-C method
/// names.
///
/// This class will either point to an IdentifierInfo or a
@@ -706,7 +717,7 @@ public:
return reinterpret_cast<void*>(InfoPtr);
}
- /// \brief Determine whether this is the empty selector.
+ /// Determine whether this is the empty selector.
bool isNull() const { return InfoPtr == 0; }
// Predicates to identify the selector type.
@@ -720,7 +731,7 @@ public:
unsigned getNumArgs() const;
- /// \brief Retrieve the identifier at a given position in the selector.
+ /// Retrieve the identifier at a given position in the selector.
///
/// Note that the identifier pointer returned may be NULL. Clients that only
/// care about the text of the identifier string, and not the specific,
@@ -735,7 +746,7 @@ public:
/// no corresponding identifier.
IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
- /// \brief Retrieve the name at a given position in the selector.
+ /// Retrieve the name at a given position in the selector.
///
/// \param argIndex The index for which we want to retrieve the name.
/// This index shall be less than \c getNumArgs() unless this is a keyword
@@ -745,14 +756,16 @@ public:
/// name was supplied.
StringRef getNameForSlot(unsigned argIndex) const;
- /// \brief Derive the full selector name (e.g. "foo:bar:") and return
+ /// Derive the full selector name (e.g. "foo:bar:") and return
/// it as an std::string.
std::string getAsString() const;
- /// \brief Prints the full selector name (e.g. "foo:bar:").
+ /// Prints the full selector name (e.g. "foo:bar:").
void print(llvm::raw_ostream &OS) const;
- /// \brief Derive the conventional family of this method.
+ void dump() const;
+
+ /// Derive the conventional family of this method.
ObjCMethodFamily getMethodFamily() const {
return getMethodFamilyImpl(*this);
}
@@ -772,7 +785,7 @@ public:
static ObjCInstanceTypeFamily getInstTypeMethodFamily(Selector sel);
};
-/// \brief This table allows us to fully hide how we implement
+/// This table allows us to fully hide how we implement
/// multi-keyword caching.
class SelectorTable {
// Actually a SelectorTableImpl
@@ -784,7 +797,7 @@ public:
SelectorTable &operator=(const SelectorTable &) = delete;
~SelectorTable();
- /// \brief Can create any sort of selector.
+ /// Can create any sort of selector.
///
/// \p NumArgs indicates whether this is a no argument selector "foo", a
/// single argument selector "foo:" or multi-argument "foo:bar:".
@@ -798,22 +811,25 @@ public:
return Selector(ID, 0);
}
- /// \brief Return the total amount of memory allocated for managing selectors.
+ /// Return the total amount of memory allocated for managing selectors.
size_t getTotalMemory() const;
- /// \brief Return the default setter name for the given identifier.
+ /// Return the default setter name for the given identifier.
///
/// This is "set" + \p Name where the initial character of \p Name
/// has been capitalized.
static SmallString<64> constructSetterName(StringRef Name);
- /// \brief Return the default setter selector for the given identifier.
+ /// Return the default setter selector for the given identifier.
///
/// This is "set" + \p Name where the initial character of \p Name
/// has been capitalized.
static Selector constructSetterSelector(IdentifierTable &Idents,
SelectorTable &SelTable,
const IdentifierInfo *Name);
+
+ /// Return the property name for the given setter selector.
+ static std::string getPropertyNameFromSetterSelector(Selector Sel);
};
/// DeclarationNameExtra - Common base of the MultiKeywordSelector,
diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h
index e60284d1b4459..8a432db911daf 100644
--- a/include/clang/Basic/LLVM.h
+++ b/include/clang/Basic/LLVM.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Forward-declares and imports various common LLVM datatypes that
+/// Forward-declares and imports various common LLVM datatypes that
/// clang wants to use unqualified.
///
//===----------------------------------------------------------------------===//
@@ -28,6 +28,7 @@ namespace llvm {
// ADT's.
class StringRef;
class Twine;
+ class VersionTuple;
template<typename T> class ArrayRef;
template<typename T> class MutableArrayRef;
template<typename T> class OwningArrayRef;
@@ -60,17 +61,18 @@ namespace clang {
using llvm::cast_or_null;
// ADT's.
- using llvm::None;
- using llvm::Optional;
- using llvm::StringRef;
- using llvm::Twine;
using llvm::ArrayRef;
using llvm::MutableArrayRef;
+ using llvm::None;
+ using llvm::Optional;
using llvm::OwningArrayRef;
+ using llvm::SaveAndRestore;
using llvm::SmallString;
using llvm::SmallVector;
using llvm::SmallVectorImpl;
- using llvm::SaveAndRestore;
+ using llvm::StringRef;
+ using llvm::Twine;
+ using llvm::VersionTuple;
// Error handling.
using llvm::Expected;
diff --git a/include/clang/Basic/Lambda.h b/include/clang/Basic/Lambda.h
index 1c19f1dcc8b1c..675854e67e7ad 100644
--- a/include/clang/Basic/Lambda.h
+++ b/include/clang/Basic/Lambda.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines several types used to describe C++ lambda expressions
+/// Defines several types used to describe C++ lambda expressions
/// that are shared between the parser and AST.
///
//===----------------------------------------------------------------------===//
@@ -19,14 +19,14 @@
namespace clang {
-/// \brief The default, if any, capture method for a lambda expression.
+/// The default, if any, capture method for a lambda expression.
enum LambdaCaptureDefault {
LCD_None,
LCD_ByCopy,
LCD_ByRef
};
-/// \brief The different capture forms in a lambda introducer
+/// The different capture forms in a lambda introducer
///
/// C++11 allows capture of \c this, or of local variables by copy or
/// by reference. C++1y also allows "init-capture", where the initializer
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index ca3a0e349d62f..fc38af5b03f6e 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -106,6 +106,7 @@ LANGOPT(LineComment , 1, 0, "'//' comments")
LANGOPT(Bool , 1, 0, "bool, true, and false keywords")
LANGOPT(Half , 1, 0, "half keyword")
LANGOPT(WChar , 1, CPlusPlus, "wchar_t keyword")
+LANGOPT(Char8 , 1, 0, "char8_t keyword")
LANGOPT(DeclSpecKeyword , 1, 0, "__declspec keyword")
BENIGN_LANGOPT(DollarIdents , 1, 1, "'$' in identifiers")
BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode")
@@ -153,6 +154,7 @@ COMPATIBLE_LANGOPT(ModulesTS , 1, 0, "C++ Modules TS")
BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 2, CMK_None,
"compiling a module interface")
BENIGN_LANGOPT(CompilingPCH, 1, 0, "building a pch")
+BENIGN_LANGOPT(BuildingPCHWithObjectFile, 1, 0, "building a pch which has a corresponding object file")
COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses")
BENIGN_LANGOPT(ModulesSearchAll , 1, 1, "searching even non-imported modules to find unresolved references")
COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "requiring declaration of module uses and all headers to be in modules")
@@ -188,21 +190,27 @@ ENUM_LANGOPT(DefaultCallingConv, DefaultCallingConvention, 3, DCC_None, "default
LANGOPT(ShortEnums , 1, 0, "short enum types")
LANGOPT(OpenCL , 1, 0, "OpenCL")
-LANGOPT(OpenCLVersion , 32, 0, "OpenCL version")
+LANGOPT(OpenCLVersion , 32, 0, "OpenCL C version")
+LANGOPT(OpenCLCPlusPlus , 1, 0, "OpenCL C++")
+LANGOPT(OpenCLCPlusPlusVersion , 32, 0, "OpenCL C++ version")
LANGOPT(NativeHalfType , 1, 0, "Native half type support")
LANGOPT(NativeHalfArgsAndReturns, 1, 0, "Native half args and returns")
LANGOPT(HalfArgsAndReturns, 1, 0, "half args and returns")
LANGOPT(CUDA , 1, 0, "CUDA")
+LANGOPT(HIP , 1, 0, "HIP")
LANGOPT(OpenMP , 32, 0, "OpenMP support and version of OpenMP (31, 40 or 45)")
+LANGOPT(OpenMPSimd , 1, 0, "Use SIMD only OpenMP support.")
LANGOPT(OpenMPUseTLS , 1, 0, "Use TLS for threadprivates or runtime calls")
LANGOPT(OpenMPIsDevice , 1, 0, "Generate code only for OpenMP target device")
+LANGOPT(OpenMPCUDAMode , 1, 0, "Generate code for OpenMP pragmas in SIMT/SPMD mode")
+LANGOPT(OpenMPHostCXXExceptions , 1, 0, "C++ exceptions handling in the host code.")
LANGOPT(RenderScript , 1, 0, "RenderScript")
LANGOPT(CUDAIsDevice , 1, 0, "compiling for CUDA device")
LANGOPT(CUDAAllowVariadicFunctions, 1, 0, "allowing variadic functions in CUDA device code")
LANGOPT(CUDAHostDeviceConstexpr, 1, 1, "treating unattributed constexpr functions as __host__ __device__")
-LANGOPT(CUDADeviceFlushDenormalsToZero, 1, 0, "flushing denormals to zero")
LANGOPT(CUDADeviceApproxTranscendentals, 1, 0, "using approximate transcendental functions")
+LANGOPT(CUDARelocatableDeviceCode, 1, 0, "generate relocatable device code")
LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
@@ -225,7 +233,7 @@ BENIGN_LANGOPT(DebuggerObjCLiteral , 1, 0, "debugger Objective-C literals and su
BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants")
LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
-/// \brief FP_CONTRACT mode (on/off/fast).
+/// FP_CONTRACT mode (on/off/fast).
ENUM_LANGOPT(DefaultFPContractMode, FPContractModeKind, 2, FPC_Off, "FP contraction type")
LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
@@ -233,11 +241,16 @@ LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")
LANGOPT(ObjCWeakRuntime , 1, 0, "__weak support in the ARC runtime")
LANGOPT(ObjCWeak , 1, 0, "Objective-C __weak in ARC and MRC files")
LANGOPT(ObjCSubscriptingLegacyRuntime , 1, 0, "Subscripting support in legacy ObjectiveC runtime")
+LANGOPT(CFProtectionBranch , 1, 0, "Control-Flow Branch Protection enabled")
LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map")
ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode")
LANGOPT(IncludeDefaultHeader, 1, 0, "Include default header file for OpenCL")
BENIGN_LANGOPT(DelayedTemplateParsing , 1, 0, "delayed template parsing")
LANGOPT(BlocksRuntimeOptional , 1, 0, "optional blocks runtime")
+LANGOPT(
+ CompleteMemberPointers, 1, 0,
+ "Require member pointer base types to be complete at the point where the "
+ "type's inheritance model would be determined under the Microsoft ABI")
ENUM_LANGOPT(GC, GCMode, 2, NonGC, "Objective-C Garbage Collection mode")
ENUM_LANGOPT(ValueVisibilityMode, Visibility, 3, DefaultVisibility,
@@ -276,10 +289,25 @@ LANGOPT(XRayInstrument, 1, 0, "controls whether to do XRay instrumentation")
LANGOPT(XRayAlwaysEmitCustomEvents, 1, 0,
"controls whether to always emit intrinsic calls to "
"__xray_customevent(...) builtin.")
+LANGOPT(XRayAlwaysEmitTypedEvents, 1, 0,
+ "controls whether to always emit intrinsic calls to "
+ "__xray_typedevent(...) builtin.")
+
+LANGOPT(ForceEmitVTables, 1, 0, "whether to emit all vtables")
BENIGN_LANGOPT(AllowEditorPlaceholders, 1, 0,
"allow editor placeholders in source")
+ENUM_LANGOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest,
+ "version of Clang that we should attempt to be ABI-compatible "
+ "with")
+
+COMPATIBLE_VALUE_LANGOPT(FunctionAlignment, 5, 0, "Default alignment for functions")
+
+LANGOPT(FixedPoint, 1, 0, "fixed point types")
+LANGOPT(PaddingOnUnsignedFixedPoint, 1, 0,
+ "unsigned fixed point types having one extra padding bit")
+
#undef LANGOPT
#undef COMPATIBLE_LANGOPT
#undef BENIGN_LANGOPT
@@ -289,4 +317,3 @@ BENIGN_LANGOPT(AllowEditorPlaceholders, 1, 0,
#undef VALUE_LANGOPT
#undef COMPATIBLE_VALUE_LANGOPT
#undef BENIGN_VALUE_LANGOPT
-
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index f7a43adefad0c..f3a6292e5adea 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -1,4 +1,4 @@
-//===--- LangOptions.h - C Language Family Language Options -----*- C++ -*-===//
+//===- LangOptions.h - C Language Family Language Options -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
-/// \brief Defines the clang::LangOptions interface.
-///
+/// Defines the clang::LangOptions interface.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_LANGOPTIONS_H
@@ -20,6 +20,8 @@
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/Visibility.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
#include <string>
#include <vector>
@@ -43,26 +45,36 @@ protected:
#include "clang/Basic/LangOptions.def"
};
-/// \brief Keeps track of the various options that can be
+/// Keeps track of the various options that can be
/// enabled, which controls the dialect of C or C++ that is accepted.
class LangOptions : public LangOptionsBase {
public:
- typedef clang::Visibility Visibility;
+ using Visibility = clang::Visibility;
enum GCMode { NonGC, GCOnly, HybridGC };
enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
enum SignedOverflowBehaviorTy {
- SOB_Undefined, // Default C standard behavior.
- SOB_Defined, // -fwrapv
- SOB_Trapping // -ftrapv
+ // Default C standard behavior.
+ SOB_Undefined,
+
+ // -fwrapv
+ SOB_Defined,
+
+ // -ftrapv
+ SOB_Trapping
};
// FIXME: Unify with TUKind.
enum CompilingModuleKind {
- CMK_None, ///< Not compiling a module interface at all.
- CMK_ModuleMap, ///< Compiling a module from a module map.
- CMK_ModuleInterface ///< Compiling a C++ modules TS module interface unit.
+ /// Not compiling a module interface at all.
+ CMK_None,
+
+ /// Compiling a module from a module map.
+ CMK_ModuleMap,
+
+ /// Compiling a C++ modules TS module interface unit.
+ CMK_ModuleInterface
};
enum PragmaMSPointersToMembersKind {
@@ -90,69 +102,109 @@ public:
MSVC2015 = 19
};
+ /// Clang versions with different platform ABI conformance.
+ enum class ClangABI {
+ /// Attempt to be ABI-compatible with code generated by Clang 3.8.x
+ /// (SVN r257626). This causes <1 x long long> to be passed in an
+ /// integer register instead of an SSE register on x64_64.
+ Ver3_8,
+
+ /// Attempt to be ABI-compatible with code generated by Clang 4.0.x
+ /// (SVN r291814). This causes move operations to be ignored when
+ /// determining whether a class type can be passed or returned directly.
+ Ver4,
+
+ /// Attempt to be ABI-compatible with code generated by Clang 6.0.x
+ /// (SVN r321711). This causes determination of whether a type is
+ /// standard-layout to ignore collisions between empty base classes
+ /// and between base classes and member subobjects, which affects
+ /// whether we reuse base class tail padding in some ABIs.
+ Ver6,
+
+ /// Conform to the underlying platform's C and C++ ABIs as closely
+ /// as we can.
+ Latest
+ };
+
enum FPContractModeKind {
- FPC_Off, // Form fused FP ops only where result will not be affected.
- FPC_On, // Form fused FP ops according to FP_CONTRACT rules.
- FPC_Fast // Aggressively fuse FP ops (E.g. FMA).
+ // Form fused FP ops only where result will not be affected.
+ FPC_Off,
+
+ // Form fused FP ops according to FP_CONTRACT rules.
+ FPC_On,
+
+ // Aggressively fuse FP ops (E.g. FMA).
+ FPC_Fast
};
public:
- /// \brief Set of enabled sanitizers.
+ /// Set of enabled sanitizers.
SanitizerSet Sanitize;
- /// \brief Paths to blacklist files specifying which objects
+ /// Paths to blacklist files specifying which objects
/// (files, functions, variables) should not be instrumented.
std::vector<std::string> SanitizerBlacklistFiles;
- /// \brief Paths to the XRay "always instrument" files specifying which
+ /// Paths to the XRay "always instrument" files specifying which
/// objects (files, functions, variables) should be imbued with the XRay
/// "always instrument" attribute.
+ /// WARNING: This is a deprecated field and will go away in the future.
std::vector<std::string> XRayAlwaysInstrumentFiles;
- /// \brief Paths to the XRay "never instrument" files specifying which
+ /// Paths to the XRay "never instrument" files specifying which
/// objects (files, functions, variables) should be imbued with the XRay
/// "never instrument" attribute.
+ /// WARNING: This is a deprecated field and will go away in the future.
std::vector<std::string> XRayNeverInstrumentFiles;
+ /// Paths to the XRay attribute list files, specifying which objects
+ /// (files, functions, variables) should be imbued with the appropriate XRay
+ /// attribute(s).
+ std::vector<std::string> XRayAttrListFiles;
+
clang::ObjCRuntime ObjCRuntime;
std::string ObjCConstantStringClass;
- /// \brief The name of the handler function to be called when -ftrapv is
+ /// The name of the handler function to be called when -ftrapv is
/// specified.
///
/// If none is specified, abort (GCC-compatible behaviour).
std::string OverflowHandler;
- /// \brief The name of the current module, of which the main source file
+ /// The module currently being compiled as speficied by -fmodule-name.
+ std::string ModuleName;
+
+ /// The name of the current module, of which the main source file
/// is a part. If CompilingModule is set, we are compiling the interface
/// of this module, otherwise we are compiling an implementation file of
- /// it.
+ /// it. This starts as ModuleName in case -fmodule-name is provided and
+ /// changes during compilation to reflect the current module.
std::string CurrentModule;
- /// \brief The names of any features to enable in module 'requires' decls
+ /// The names of any features to enable in module 'requires' decls
/// in addition to the hard-coded list in Module.cpp and the target features.
///
/// This list is sorted.
std::vector<std::string> ModuleFeatures;
- /// \brief Options for parsing comments.
+ /// Options for parsing comments.
CommentOptions CommentOpts;
- /// \brief A list of all -fno-builtin-* function names (e.g., memset).
+ /// A list of all -fno-builtin-* function names (e.g., memset).
std::vector<std::string> NoBuiltinFuncs;
- /// \brief Triples of the OpenMP targets that the host code codegen should
+ /// Triples of the OpenMP targets that the host code codegen should
/// take into account in order to generate accurate offloading descriptors.
std::vector<llvm::Triple> OMPTargetTriples;
- /// \brief Name of the IR file that contains the result of the OpenMP target
+ /// Name of the IR file that contains the result of the OpenMP target
/// host code generation.
std::string OMPHostIRFile;
- /// \brief Indicates whether the front-end is explicitly told that the
+ /// Indicates whether the front-end is explicitly told that the
/// input is a header file (i.e. -x c-header).
- bool IsHeaderFile;
+ bool IsHeaderFile = false;
LangOptions();
@@ -186,15 +238,15 @@ public:
return MSCompatibilityVersion >= MajorVersion * 10000000U;
}
- /// \brief Reset all of the options that are not considered when building a
+ /// Reset all of the options that are not considered when building a
/// module.
void resetNonModularOptions();
- /// \brief Is this a libc/libm function that is no longer recognized as a
+ /// Is this a libc/libm function that is no longer recognized as a
/// builtin because a -fno-builtin-* option has been specified?
bool isNoBuiltinFunc(StringRef Name) const;
- /// \brief True if any ObjC types may have non-trivial lifetime qualifiers.
+ /// True if any ObjC types may have non-trivial lifetime qualifiers.
bool allowsNonTrivialObjCLifetimeQualifiers() const {
return ObjCAutoRefCount || ObjCWeak;
}
@@ -202,9 +254,12 @@ public:
bool assumeFunctionsAreConvergent() const {
return (CUDA && CUDAIsDevice) || OpenCL;
}
+
+ /// Return the OpenCL C or C++ version as a VersionTuple.
+ VersionTuple getOpenCLVersionTuple() const;
};
-/// \brief Floating point control options
+/// Floating point control options
class FPOptions {
public:
FPOptions() : fp_contract(LangOptions::FPC_Off) {}
@@ -219,15 +274,19 @@ public:
bool allowFPContractWithinStatement() const {
return fp_contract == LangOptions::FPC_On;
}
+
bool allowFPContractAcrossStatement() const {
return fp_contract == LangOptions::FPC_Fast;
}
+
void setAllowFPContractWithinStatement() {
fp_contract = LangOptions::FPC_On;
}
+
void setAllowFPContractAcrossStatement() {
fp_contract = LangOptions::FPC_Fast;
}
+
void setDisallowFPContract() { fp_contract = LangOptions::FPC_Off; }
/// Used to serialize this.
@@ -238,17 +297,19 @@ private:
unsigned fp_contract : 2;
};
-/// \brief Describes the kind of translation unit being processed.
+/// Describes the kind of translation unit being processed.
enum TranslationUnitKind {
- /// \brief The translation unit is a complete translation unit.
+ /// The translation unit is a complete translation unit.
TU_Complete,
- /// \brief The translation unit is a prefix to a translation unit, and is
+
+ /// The translation unit is a prefix to a translation unit, and is
/// not complete.
TU_Prefix,
- /// \brief The translation unit is a module.
+
+ /// The translation unit is a module.
TU_Module
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_BASIC_LANGOPTIONS_H
diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h
index 6ec8763f24910..94dcfd445b0b7 100644
--- a/include/clang/Basic/Linkage.h
+++ b/include/clang/Basic/Linkage.h
@@ -1,4 +1,4 @@
-//===--- Linkage.h - Linkage enumeration and utilities ----------*- C++ -*-===//
+//===- Linkage.h - Linkage enumeration and utilities ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,33 +6,32 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
-/// \brief Defines the Linkage enumeration and various utility functions.
-///
+/// Defines the Linkage enumeration and various utility functions.
+//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_BASIC_LINKAGE_H
#define LLVM_CLANG_BASIC_LINKAGE_H
-#include <assert.h>
-#include <stdint.h>
#include <utility>
namespace clang {
-/// \brief Describes the different kinds of linkage
+/// Describes the different kinds of linkage
/// (C++ [basic.link], C99 6.2.2) that an entity may have.
enum Linkage : unsigned char {
- /// \brief No linkage, which means that the entity is unique and
+ /// No linkage, which means that the entity is unique and
/// can only be referred to from within its scope.
NoLinkage = 0,
- /// \brief Internal linkage, which indicates that the entity can
+ /// Internal linkage, which indicates that the entity can
/// be referred to from within the translation unit (but not other
/// translation units).
InternalLinkage,
- /// \brief External linkage within a unique namespace.
+ /// External linkage within a unique namespace.
///
/// From the language perspective, these entities have external
/// linkage. However, since they reside in an anonymous namespace,
@@ -41,27 +40,27 @@ enum Linkage : unsigned char {
/// point of view.
UniqueExternalLinkage,
- /// \brief No linkage according to the standard, but is visible from other
+ /// No linkage according to the standard, but is visible from other
/// translation units because of types defined in a inline function.
VisibleNoLinkage,
- /// \brief Internal linkage according to the Modules TS, but can be referred
+ /// Internal linkage according to the Modules TS, but can be referred
/// to from other translation units indirectly through inline functions and
/// templates in the module interface.
ModuleInternalLinkage,
- /// \brief Module linkage, which indicates that the entity can be referred
+ /// Module linkage, which indicates that the entity can be referred
/// to from other translation units within the same module, and indirectly
/// from arbitrary other translation units through inline functions and
/// templates in the module interface.
ModuleLinkage,
- /// \brief External linkage, which indicates that the entity can
+ /// External linkage, which indicates that the entity can
/// be referred to from other translation units.
ExternalLinkage
};
-/// \brief Describes the different kinds of language linkage
+/// Describes the different kinds of language linkage
/// (C++ [dcl.link]) that an entity may have.
enum LanguageLinkage {
CLanguageLinkage,
@@ -69,7 +68,7 @@ enum LanguageLinkage {
NoLanguageLinkage
};
-/// \brief A more specific kind of linkage than enum Linkage.
+/// A more specific kind of linkage than enum Linkage.
///
/// This is relevant to CodeGen and AST file reading.
enum GVALinkage {
@@ -105,7 +104,7 @@ inline bool isExternalFormalLinkage(Linkage L) {
return getFormalLinkage(L) == ExternalLinkage;
}
-/// \brief Compute the minimum linkage given two linkages.
+/// Compute the minimum linkage given two linkages.
///
/// The linkage can be interpreted as a pair formed by the formal linkage and
/// a boolean for external visibility. This is just what getFormalLinkage and
@@ -125,6 +124,6 @@ inline Linkage minLinkage(Linkage L1, Linkage L2) {
return L1 < L2 ? L1 : L2;
}
-} // end namespace clang
+} // namespace clang
#endif // LLVM_CLANG_BASIC_LINKAGE_H
diff --git a/include/clang/Basic/MacroBuilder.h b/include/clang/Basic/MacroBuilder.h
index 9a9eaa24983ca..b2edc972fee22 100644
--- a/include/clang/Basic/MacroBuilder.h
+++ b/include/clang/Basic/MacroBuilder.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the clang::MacroBuilder utility class.
+/// Defines the clang::MacroBuilder utility class.
///
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 6631721e35314..4aebda1887c45 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Defines the clang::Module class, which describes a module in the
+/// Defines the clang::Module class, which describes a module in the
/// source code.
//
//===----------------------------------------------------------------------===//
@@ -48,7 +48,7 @@ namespace clang {
class LangOptions;
class TargetInfo;
-/// \brief Describes the name of a module.
+/// Describes the name of a module.
using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>;
/// The signature of a module, which is a hash of the AST content.
@@ -61,76 +61,76 @@ struct ASTFileSignature : std::array<uint32_t, 5> {
}
};
-/// \brief Describes a module or submodule.
+/// Describes a module or submodule.
class Module {
public:
- /// \brief The name of this module.
+ /// The name of this module.
std::string Name;
- /// \brief The location of the module definition.
+ /// The location of the module definition.
SourceLocation DefinitionLoc;
enum ModuleKind {
- /// \brief This is a module that was defined by a module map and built out
+ /// This is a module that was defined by a module map and built out
/// of header files.
ModuleMapModule,
- /// \brief This is a C++ Modules TS module interface unit.
+ /// This is a C++ Modules TS module interface unit.
ModuleInterfaceUnit,
- /// \brief This is a fragment of the global module within some C++ Modules
+ /// This is a fragment of the global module within some C++ Modules
/// TS module.
GlobalModuleFragment,
};
- /// \brief The kind of this module.
+ /// The kind of this module.
ModuleKind Kind = ModuleMapModule;
- /// \brief The parent of this module. This will be NULL for the top-level
+ /// The parent of this module. This will be NULL for the top-level
/// module.
Module *Parent;
- /// \brief The build directory of this module. This is the directory in
+ /// The build directory of this module. This is the directory in
/// which the module is notionally built, and relative to which its headers
/// are found.
const DirectoryEntry *Directory = nullptr;
- /// \brief The presumed file name for the module map defining this module.
+ /// The presumed file name for the module map defining this module.
/// Only non-empty when building from preprocessed source.
std::string PresumedModuleMapFile;
- /// \brief The umbrella header or directory.
+ /// The umbrella header or directory.
llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
- /// \brief The module signature.
+ /// The module signature.
ASTFileSignature Signature;
- /// \brief The name of the umbrella entry, as written in the module map.
+ /// The name of the umbrella entry, as written in the module map.
std::string UmbrellaAsWritten;
- /// \brief The module through which entities defined in this module will
+ /// The module through which entities defined in this module will
/// eventually be exposed, for use in "private" modules.
std::string ExportAsModule;
private:
- /// \brief The submodules of this module, indexed by name.
+ /// The submodules of this module, indexed by name.
std::vector<Module *> SubModules;
- /// \brief A mapping from the submodule name to the index into the
+ /// A mapping from the submodule name to the index into the
/// \c SubModules vector at which that submodule resides.
llvm::StringMap<unsigned> SubModuleIndex;
- /// \brief The AST file if this is a top-level module which has a
+ /// The AST file if this is a top-level module which has a
/// corresponding serialized AST file, or null otherwise.
const FileEntry *ASTFile = nullptr;
- /// \brief The top-level headers associated with this module.
+ /// The top-level headers associated with this module.
llvm::SmallSetVector<const FileEntry *, 2> TopHeaders;
- /// \brief top-level header filenames that aren't resolved to FileEntries yet.
+ /// top-level header filenames that aren't resolved to FileEntries yet.
std::vector<std::string> TopHeaderNames;
- /// \brief Cache of modules visible to lookup in this module.
+ /// Cache of modules visible to lookup in this module.
mutable llvm::DenseSet<const Module*> VisibleModulesCache;
/// The ID used when referencing this module within a VisibleModuleSet.
@@ -146,7 +146,7 @@ public:
};
static const int NumHeaderKinds = HK_Excluded + 1;
- /// \brief Information about a header directive as found in the module map
+ /// Information about a header directive as found in the module map
/// file.
struct Header {
std::string NameAsWritten;
@@ -155,7 +155,7 @@ public:
explicit operator bool() { return Entry; }
};
- /// \brief Information about a directory name as found in the module map
+ /// Information about a directory name as found in the module map
/// file.
struct DirectoryName {
std::string NameAsWritten;
@@ -164,10 +164,10 @@ public:
explicit operator bool() { return Entry; }
};
- /// \brief The headers that are part of this module.
+ /// The headers that are part of this module.
SmallVector<Header, 2> Headers[5];
- /// \brief Stored information about a header directive that was found in the
+ /// Stored information about a header directive that was found in the
/// module map file but has not been resolved to a file.
struct UnresolvedHeaderDirective {
HeaderKind Kind = HK_Normal;
@@ -183,191 +183,202 @@ public:
/// yet attempted to resolve to a file on the file system.
SmallVector<UnresolvedHeaderDirective, 1> UnresolvedHeaders;
- /// \brief Headers that are mentioned in the module map file but could not be
+ /// Headers that are mentioned in the module map file but could not be
/// found on the file system.
SmallVector<UnresolvedHeaderDirective, 1> MissingHeaders;
- /// \brief An individual requirement: a feature name and a flag indicating
+ /// An individual requirement: a feature name and a flag indicating
/// the required state of that feature.
using Requirement = std::pair<std::string, bool>;
- /// \brief The set of language features required to use this module.
+ /// The set of language features required to use this module.
///
/// If any of these requirements are not available, the \c IsAvailable bit
/// will be false to indicate that this (sub)module is not available.
SmallVector<Requirement, 2> Requirements;
- /// \brief Whether this module is missing a feature from \c Requirements.
+ /// A module with the same name that shadows this module.
+ Module *ShadowingModule = nullptr;
+
+ /// Whether this module is missing a feature from \c Requirements.
unsigned IsMissingRequirement : 1;
- /// \brief Whether we tried and failed to load a module file for this module.
+ /// Whether we tried and failed to load a module file for this module.
unsigned HasIncompatibleModuleFile : 1;
- /// \brief Whether this module is available in the current translation unit.
+ /// Whether this module is available in the current translation unit.
///
/// If the module is missing headers or does not meet all requirements then
/// this bit will be 0.
unsigned IsAvailable : 1;
- /// \brief Whether this module was loaded from a module file.
+ /// Whether this module was loaded from a module file.
unsigned IsFromModuleFile : 1;
- /// \brief Whether this is a framework module.
+ /// Whether this is a framework module.
unsigned IsFramework : 1;
- /// \brief Whether this is an explicit submodule.
+ /// Whether this is an explicit submodule.
unsigned IsExplicit : 1;
- /// \brief Whether this is a "system" module (which assumes that all
+ /// Whether this is a "system" module (which assumes that all
/// headers in it are system headers).
unsigned IsSystem : 1;
- /// \brief Whether this is an 'extern "C"' module (which implicitly puts all
+ /// Whether this is an 'extern "C"' module (which implicitly puts all
/// headers in it within an 'extern "C"' block, and allows the module to be
/// imported within such a block).
unsigned IsExternC : 1;
- /// \brief Whether this is an inferred submodule (module * { ... }).
+ /// Whether this is an inferred submodule (module * { ... }).
unsigned IsInferred : 1;
- /// \brief Whether we should infer submodules for this module based on
+ /// Whether we should infer submodules for this module based on
/// the headers.
///
/// Submodules can only be inferred for modules with an umbrella header.
unsigned InferSubmodules : 1;
- /// \brief Whether, when inferring submodules, the inferred submodules
+ /// Whether, when inferring submodules, the inferred submodules
/// should be explicit.
unsigned InferExplicitSubmodules : 1;
- /// \brief Whether, when inferring submodules, the inferr submodules should
+ /// Whether, when inferring submodules, the inferr submodules should
/// export all modules they import (e.g., the equivalent of "export *").
unsigned InferExportWildcard : 1;
- /// \brief Whether the set of configuration macros is exhaustive.
+ /// Whether the set of configuration macros is exhaustive.
///
/// When the set of configuration macros is exhaustive, meaning
/// that no identifier not in this list should affect how the module is
/// built.
unsigned ConfigMacrosExhaustive : 1;
- /// \brief Whether files in this module can only include non-modular headers
+ /// Whether files in this module can only include non-modular headers
/// and headers from used modules.
unsigned NoUndeclaredIncludes : 1;
- /// \brief Describes the visibility of the various names within a
+ /// Whether this module came from a "private" module map, found next
+ /// to a regular (public) module map.
+ unsigned ModuleMapIsPrivate : 1;
+
+ /// Describes the visibility of the various names within a
/// particular module.
enum NameVisibilityKind {
- /// \brief All of the names in this module are hidden.
+ /// All of the names in this module are hidden.
Hidden,
- /// \brief All of the names in this module are visible.
+ /// All of the names in this module are visible.
AllVisible
};
- /// \brief The visibility of names within this particular module.
+ /// The visibility of names within this particular module.
NameVisibilityKind NameVisibility;
- /// \brief The location of the inferred submodule.
+ /// The location of the inferred submodule.
SourceLocation InferredSubmoduleLoc;
- /// \brief The set of modules imported by this module, and on which this
+ /// The set of modules imported by this module, and on which this
/// module depends.
llvm::SmallSetVector<Module *, 2> Imports;
- /// \brief Describes an exported module.
+ /// Describes an exported module.
///
/// The pointer is the module being re-exported, while the bit will be true
/// to indicate that this is a wildcard export.
using ExportDecl = llvm::PointerIntPair<Module *, 1, bool>;
- /// \brief The set of export declarations.
+ /// The set of export declarations.
SmallVector<ExportDecl, 2> Exports;
- /// \brief Describes an exported module that has not yet been resolved
+ /// Describes an exported module that has not yet been resolved
/// (perhaps because the module it refers to has not yet been loaded).
struct UnresolvedExportDecl {
- /// \brief The location of the 'export' keyword in the module map file.
+ /// The location of the 'export' keyword in the module map file.
SourceLocation ExportLoc;
- /// \brief The name of the module.
+ /// The name of the module.
ModuleId Id;
- /// \brief Whether this export declaration ends in a wildcard, indicating
+ /// Whether this export declaration ends in a wildcard, indicating
/// that all of its submodules should be exported (rather than the named
/// module itself).
bool Wildcard;
};
- /// \brief The set of export declarations that have yet to be resolved.
+ /// The set of export declarations that have yet to be resolved.
SmallVector<UnresolvedExportDecl, 2> UnresolvedExports;
- /// \brief The directly used modules.
+ /// The directly used modules.
SmallVector<Module *, 2> DirectUses;
- /// \brief The set of use declarations that have yet to be resolved.
+ /// The set of use declarations that have yet to be resolved.
SmallVector<ModuleId, 2> UnresolvedDirectUses;
- /// \brief A library or framework to link against when an entity from this
+ /// A library or framework to link against when an entity from this
/// module is used.
struct LinkLibrary {
LinkLibrary() = default;
LinkLibrary(const std::string &Library, bool IsFramework)
: Library(Library), IsFramework(IsFramework) {}
- /// \brief The library to link against.
+ /// The library to link against.
///
/// This will typically be a library or framework name, but can also
/// be an absolute path to the library or framework.
std::string Library;
- /// \brief Whether this is a framework rather than a library.
+ /// Whether this is a framework rather than a library.
bool IsFramework = false;
};
- /// \brief The set of libraries or frameworks to link against when
+ /// The set of libraries or frameworks to link against when
/// an entity from this module is used.
llvm::SmallVector<LinkLibrary, 2> LinkLibraries;
- /// \brief The set of "configuration macros", which are macros that
+ /// Autolinking uses the framework name for linking purposes
+ /// when this is false and the export_as name otherwise.
+ bool UseExportAsModuleLinkName = false;
+
+ /// The set of "configuration macros", which are macros that
/// (intentionally) change how this module is built.
std::vector<std::string> ConfigMacros;
- /// \brief An unresolved conflict with another module.
+ /// An unresolved conflict with another module.
struct UnresolvedConflict {
- /// \brief The (unresolved) module id.
+ /// The (unresolved) module id.
ModuleId Id;
- /// \brief The message provided to the user when there is a conflict.
+ /// The message provided to the user when there is a conflict.
std::string Message;
};
- /// \brief The list of conflicts for which the module-id has not yet been
+ /// The list of conflicts for which the module-id has not yet been
/// resolved.
std::vector<UnresolvedConflict> UnresolvedConflicts;
- /// \brief A conflict between two modules.
+ /// A conflict between two modules.
struct Conflict {
- /// \brief The module that this module conflicts with.
+ /// The module that this module conflicts with.
Module *Other;
- /// \brief The message provided to the user when there is a conflict.
+ /// The message provided to the user when there is a conflict.
std::string Message;
};
- /// \brief The list of conflicts.
+ /// The list of conflicts.
std::vector<Conflict> Conflicts;
- /// \brief Construct a new module or submodule.
+ /// Construct a new module or submodule.
Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
bool IsFramework, bool IsExplicit, unsigned VisibilityID);
~Module();
- /// \brief Determine whether this module is available for use within the
+ /// Determine whether this module is available for use within the
/// current translation unit.
bool isAvailable() const { return IsAvailable; }
- /// \brief Determine whether this module is available for use within the
+ /// Determine whether this module is available for use within the
/// current translation unit.
///
/// \param LangOpts The language options used for the current
@@ -375,22 +386,29 @@ public:
///
/// \param Target The target options used for the current translation unit.
///
- /// \param Req If this module is unavailable, this parameter
- /// will be set to one of the requirements that is not met for use of
- /// this module.
+ /// \param Req If this module is unavailable because of a missing requirement,
+ /// this parameter will be set to one of the requirements that is not met for
+ /// use of this module.
+ ///
+ /// \param MissingHeader If this module is unavailable because of a missing
+ /// header, this parameter will be set to one of the missing headers.
+ ///
+ /// \param ShadowingModule If this module is unavailable because it is
+ /// shadowed, this parameter will be set to the shadowing module.
bool isAvailable(const LangOptions &LangOpts,
const TargetInfo &Target,
Requirement &Req,
- UnresolvedHeaderDirective &MissingHeader) const;
+ UnresolvedHeaderDirective &MissingHeader,
+ Module *&ShadowingModule) const;
- /// \brief Determine whether this module is a submodule.
+ /// Determine whether this module is a submodule.
bool isSubModule() const { return Parent != nullptr; }
- /// \brief Determine whether this module is a submodule of the given other
+ /// Determine whether this module is a submodule of the given other
/// module.
bool isSubModuleOf(const Module *Other) const;
- /// \brief Determine whether this module is a part of a framework,
+ /// Determine whether this module is a part of a framework,
/// either because it is a framework module or because it is a submodule
/// of a framework module.
bool isPartOfFramework() const {
@@ -401,7 +419,7 @@ public:
return false;
}
- /// \brief Determine whether this module is a subframework of another
+ /// Determine whether this module is a subframework of another
/// framework.
bool isSubFramework() const {
return IsFramework && Parent && Parent->isPartOfFramework();
@@ -416,51 +434,51 @@ public:
Parent->SubModules.push_back(this);
}
- /// \brief Retrieve the full name of this module, including the path from
+ /// Retrieve the full name of this module, including the path from
/// its top-level module.
/// \param AllowStringLiterals If \c true, components that might not be
/// lexically valid as identifiers will be emitted as string literals.
std::string getFullModuleName(bool AllowStringLiterals = false) const;
- /// \brief Whether the full name of this module is equal to joining
+ /// Whether the full name of this module is equal to joining
/// \p nameParts with "."s.
///
/// This is more efficient than getFullModuleName().
bool fullModuleNameIs(ArrayRef<StringRef> nameParts) const;
- /// \brief Retrieve the top-level module for this (sub)module, which may
+ /// Retrieve the top-level module for this (sub)module, which may
/// be this module.
Module *getTopLevelModule() {
return const_cast<Module *>(
const_cast<const Module *>(this)->getTopLevelModule());
}
- /// \brief Retrieve the top-level module for this (sub)module, which may
+ /// Retrieve the top-level module for this (sub)module, which may
/// be this module.
const Module *getTopLevelModule() const;
- /// \brief Retrieve the name of the top-level module.
+ /// Retrieve the name of the top-level module.
StringRef getTopLevelModuleName() const {
return getTopLevelModule()->Name;
}
- /// \brief The serialized AST file for this module, if one was created.
+ /// The serialized AST file for this module, if one was created.
const FileEntry *getASTFile() const {
return getTopLevelModule()->ASTFile;
}
- /// \brief Set the serialized AST file for the top-level module of this module.
+ /// Set the serialized AST file for the top-level module of this module.
void setASTFile(const FileEntry *File) {
assert((File == nullptr || getASTFile() == nullptr ||
getASTFile() == File) && "file path changed");
getTopLevelModule()->ASTFile = File;
}
- /// \brief Retrieve the directory for which this module serves as the
+ /// Retrieve the directory for which this module serves as the
/// umbrella.
DirectoryName getUmbrellaDir() const;
- /// \brief Retrieve the header that serves as the umbrella header for this
+ /// Retrieve the header that serves as the umbrella header for this
/// module.
Header getUmbrellaHeader() const {
if (auto *E = Umbrella.dyn_cast<const FileEntry *>())
@@ -468,31 +486,31 @@ public:
return Header{};
}
- /// \brief Determine whether this module has an umbrella directory that is
+ /// Determine whether this module has an umbrella directory that is
/// not based on an umbrella header.
bool hasUmbrellaDir() const {
return Umbrella && Umbrella.is<const DirectoryEntry *>();
}
- /// \brief Add a top-level header associated with this module.
+ /// Add a top-level header associated with this module.
void addTopHeader(const FileEntry *File) {
assert(File);
TopHeaders.insert(File);
}
- /// \brief Add a top-level header filename associated with this module.
+ /// Add a top-level header filename associated with this module.
void addTopHeaderFilename(StringRef Filename) {
TopHeaderNames.push_back(Filename);
}
- /// \brief The top-level headers associated with this module.
+ /// The top-level headers associated with this module.
ArrayRef<const FileEntry *> getTopHeaders(FileManager &FileMgr);
- /// \brief Determine whether this module has declared its intention to
+ /// Determine whether this module has declared its intention to
/// directly use another module.
bool directlyUses(const Module *Requested) const;
- /// \brief Add the given feature requirement to the list of features
+ /// Add the given feature requirement to the list of features
/// required by this module.
///
/// \param Feature The feature that is required by this module (and
@@ -510,15 +528,15 @@ public:
const LangOptions &LangOpts,
const TargetInfo &Target);
- /// \brief Mark this module and all of its submodules as unavailable.
+ /// Mark this module and all of its submodules as unavailable.
void markUnavailable(bool MissingRequirement = false);
- /// \brief Find the submodule with the given name.
+ /// Find the submodule with the given name.
///
/// \returns The submodule if found, or NULL otherwise.
Module *findSubmodule(StringRef Name) const;
- /// \brief Determine whether the specified module would be visible to
+ /// Determine whether the specified module would be visible to
/// a lookup at the end of this module.
///
/// FIXME: This may return incorrect results for (submodules of) the
@@ -547,7 +565,7 @@ public:
return llvm::make_range(submodule_begin(), submodule_end());
}
- /// \brief Appends this module's list of exported modules to \p Exported.
+ /// Appends this module's list of exported modules to \p Exported.
///
/// This provides a subset of immediately imported modules (the ones that are
/// directly exported), not the complete set of exported modules.
@@ -557,17 +575,17 @@ public:
return "<module-includes>";
}
- /// \brief Print the module map for this module to the given stream.
+ /// Print the module map for this module to the given stream.
void print(raw_ostream &OS, unsigned Indent = 0) const;
- /// \brief Dump the contents of this module to the given output stream.
+ /// Dump the contents of this module to the given output stream.
void dump() const;
private:
void buildVisibleModulesCache() const;
};
-/// \brief A set of visible modules.
+/// A set of visible modules.
class VisibleModuleSet {
public:
VisibleModuleSet() = default;
@@ -587,34 +605,34 @@ public:
return *this;
}
- /// \brief Get the current visibility generation. Incremented each time the
+ /// Get the current visibility generation. Incremented each time the
/// set of visible modules changes in any way.
unsigned getGeneration() const { return Generation; }
- /// \brief Determine whether a module is visible.
+ /// Determine whether a module is visible.
bool isVisible(const Module *M) const {
return getImportLoc(M).isValid();
}
- /// \brief Get the location at which the import of a module was triggered.
+ /// Get the location at which the import of a module was triggered.
SourceLocation getImportLoc(const Module *M) const {
return M->getVisibilityID() < ImportLocs.size()
? ImportLocs[M->getVisibilityID()]
: SourceLocation();
}
- /// \brief A callback to call when a module is made visible (directly or
+ /// A callback to call when a module is made visible (directly or
/// indirectly) by a call to \ref setVisible.
using VisibleCallback = llvm::function_ref<void(Module *M)>;
- /// \brief A callback to call when a module conflict is found. \p Path
+ /// A callback to call when a module conflict is found. \p Path
/// consists of a sequence of modules from the conflicting module to the one
/// made visible, where each was exported by the next.
using ConflictCallback =
llvm::function_ref<void(ArrayRef<Module *> Path, Module *Conflict,
StringRef Message)>;
- /// \brief Make a specific module visible.
+ /// Make a specific module visible.
void setVisible(Module *M, SourceLocation Loc,
VisibleCallback Vis = [](Module *) {},
ConflictCallback Cb = [](ArrayRef<Module *>, Module *,
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index 8dc259c7ab66f..d5f4f50fe36f5 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -1,4 +1,4 @@
-//===--- ObjCRuntime.h - Objective-C Runtime Configuration ------*- C++ -*-===//
+//===- ObjCRuntime.h - Objective-C Runtime Configuration --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,25 +6,28 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
-/// \brief Defines types useful for describing an Objective-C runtime.
-///
+/// Defines types useful for describing an Objective-C runtime.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_OBJCRUNTIME_H
#define LLVM_CLANG_BASIC_OBJCRUNTIME_H
-#include "clang/Basic/VersionTuple.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/VersionTuple.h"
+#include <string>
namespace clang {
-/// \brief The basic abstraction for the target Objective-C runtime.
+/// The basic abstraction for the target Objective-C runtime.
class ObjCRuntime {
public:
- /// \brief The basic Objective-C runtimes that we know about.
+ /// The basic Objective-C runtimes that we know about.
enum Kind {
/// 'macosx' is the Apple-provided NeXT-derived runtime on Mac OS
/// X platforms that use the non-fragile ABI; the version is a
@@ -57,15 +60,14 @@ public:
};
private:
- Kind TheKind;
+ Kind TheKind = MacOSX;
VersionTuple Version;
public:
/// A bogus initialization of the runtime.
- ObjCRuntime() : TheKind(MacOSX) {}
-
+ ObjCRuntime() = default;
ObjCRuntime(Kind kind, const VersionTuple &version)
- : TheKind(kind), Version(version) {}
+ : TheKind(kind), Version(version) {}
void set(Kind kind, VersionTuple version) {
TheKind = kind;
@@ -75,7 +77,7 @@ public:
Kind getKind() const { return TheKind; }
const VersionTuple &getVersion() const { return Version; }
- /// \brief Does this runtime follow the set of implied behaviors for a
+ /// Does this runtime follow the set of implied behaviors for a
/// "non-fragile" ABI?
bool isNonFragile() const {
switch (getKind()) {
@@ -113,7 +115,7 @@ public:
return true;
}
- /// \brief Is this runtime basically of the GNU family of runtimes?
+ /// Is this runtime basically of the GNU family of runtimes?
bool isGNUFamily() const {
switch (getKind()) {
case FragileMacOSX:
@@ -129,14 +131,14 @@ public:
llvm_unreachable("bad kind");
}
- /// \brief Is this runtime basically of the NeXT family of runtimes?
+ /// Is this runtime basically of the NeXT family of runtimes?
bool isNeXTFamily() const {
// For now, this is just the inverse of isGNUFamily(), but that's
// not inherently true.
return !isGNUFamily();
}
- /// \brief Does this runtime allow ARC at all?
+ /// Does this runtime allow ARC at all?
bool allowsARC() const {
switch (getKind()) {
case FragileMacOSX:
@@ -152,7 +154,7 @@ public:
llvm_unreachable("bad kind");
}
- /// \brief Does this runtime natively provide the ARC entrypoints?
+ /// Does this runtime natively provide the ARC entrypoints?
///
/// ARC cannot be directly supported on a platform that does not provide
/// these entrypoints, although it may be supportable via a stub
@@ -171,7 +173,7 @@ public:
llvm_unreachable("bad kind");
}
- /// \brief Does this runtime supports optimized setter entrypoints?
+ /// Does this runtime supports optimized setter entrypoints?
bool hasOptimizedSetter() const {
switch (getKind()) {
case MacOSX:
@@ -182,9 +184,8 @@ public:
return true;
case GNUstep:
return getVersion() >= VersionTuple(1, 7);
-
default:
- return false;
+ return false;
}
}
@@ -193,7 +194,7 @@ public:
return hasNativeWeak();
}
- /// \brief Does this runtime natively provide ARC-compliant 'weak'
+ /// Does this runtime natively provide ARC-compliant 'weak'
/// entrypoints?
bool hasNativeWeak() const {
// Right now, this is always equivalent to whether the runtime
@@ -201,14 +202,14 @@ public:
return hasNativeARC();
}
- /// \brief Does this runtime directly support the subscripting methods?
+ /// Does this runtime directly support the subscripting methods?
///
/// This is really a property of the library, not the runtime.
bool hasSubscripting() const {
switch (getKind()) {
case FragileMacOSX: return false;
- case MacOSX: return getVersion() >= VersionTuple(10, 8);
- case iOS: return getVersion() >= VersionTuple(6);
+ case MacOSX: return getVersion() >= VersionTuple(10, 11);
+ case iOS: return getVersion() >= VersionTuple(9);
case WatchOS: return true;
// This is really a lie, because some implementations and versions
@@ -221,12 +222,12 @@ public:
llvm_unreachable("bad kind");
}
- /// \brief Does this runtime allow sizeof or alignof on object types?
+ /// Does this runtime allow sizeof or alignof on object types?
bool allowsSizeofAlignof() const {
return isFragile();
}
- /// \brief Does this runtime allow pointer arithmetic on objects?
+ /// Does this runtime allow pointer arithmetic on objects?
///
/// This covers +, -, ++, --, and (if isSubscriptPointerArithmetic()
/// yields true) [].
@@ -245,12 +246,12 @@ public:
llvm_unreachable("bad kind");
}
- /// \brief Is subscripting pointer arithmetic?
+ /// Is subscripting pointer arithmetic?
bool isSubscriptPointerArithmetic() const {
return allowsPointerArithmetic();
}
- /// \brief Does this runtime provide an objc_terminate function?
+ /// Does this runtime provide an objc_terminate function?
///
/// This is used in handlers for exceptions during the unwind process;
/// without it, abort() must be used in pure ObjC files.
@@ -267,7 +268,7 @@ public:
llvm_unreachable("bad kind");
}
- /// \brief Does this runtime support weakly importing classes?
+ /// Does this runtime support weakly importing classes?
bool hasWeakClassImport() const {
switch (getKind()) {
case MacOSX: return true;
@@ -281,7 +282,7 @@ public:
llvm_unreachable("bad kind");
}
- /// \brief Does this runtime use zero-cost exceptions?
+ /// Does this runtime use zero-cost exceptions?
bool hasUnwindExceptions() const {
switch (getKind()) {
case MacOSX: return true;
@@ -320,7 +321,6 @@ public:
return getVersion() >= VersionTuple(2);
case GNUstep:
return false;
-
default:
return false;
}
@@ -340,7 +340,7 @@ public:
}
}
- /// \brief Try to parse an Objective-C runtime specification from the given
+ /// Try to parse an Objective-C runtime specification from the given
/// string.
///
/// \return true on error.
@@ -360,6 +360,6 @@ public:
raw_ostream &operator<<(raw_ostream &out, const ObjCRuntime &value);
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_BASIC_OBJCRUNTIME_H
diff --git a/include/clang/Basic/OpenCLExtensions.def b/include/clang/Basic/OpenCLExtensions.def
index c3319d2d808b9..13cb12e7c5811 100644
--- a/include/clang/Basic/OpenCLExtensions.def
+++ b/include/clang/Basic/OpenCLExtensions.def
@@ -53,6 +53,9 @@ OPENCLEXT_INTERNAL(cl_khr_icd, 100, ~0U)
OPENCLEXT_INTERNAL(cl_khr_gl_event, 110, ~0U)
OPENCLEXT_INTERNAL(cl_khr_d3d10_sharing, 110, ~0U)
+// EMBEDDED_PROFILE
+OPENCLEXT_INTERNAL(cles_khr_int64, 110, ~0U)
+
// OpenCL 1.2.
OPENCLEXT_INTERNAL(cl_khr_context_abort, 120, ~0U)
OPENCLEXT_INTERNAL(cl_khr_d3d11_sharing, 120, ~0U)
diff --git a/include/clang/Basic/OpenCLOptions.h b/include/clang/Basic/OpenCLOptions.h
index cc850f0b0b24a..cc4e9922dca03 100644
--- a/include/clang/Basic/OpenCLOptions.h
+++ b/include/clang/Basic/OpenCLOptions.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the clang::OpenCLOptions class.
+/// Defines the clang::OpenCLOptions class.
///
//===----------------------------------------------------------------------===//
@@ -19,7 +19,7 @@
namespace clang {
-/// \brief OpenCL supported extensions and optional core features
+/// OpenCL supported extensions and optional core features
class OpenCLOptions {
struct Info {
bool Supported; // Is this option supported
@@ -67,7 +67,7 @@ public:
OptMap[Ext].Enabled = V;
}
- /// \brief Enable or disable support for OpenCL extensions
+ /// Enable or disable support for OpenCL extensions
/// \param Ext name of the extension optionally prefixed with
/// '+' or '-'
/// \param V used when \p Ext is not prefixed by '+' or '-'
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index 6a0bed7ab15fc..4ed7053b679b2 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
/// \file
-/// \brief This file defines the list of supported OpenMP directives and
+/// This file defines the list of supported OpenMP directives and
/// clauses.
///
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h
index e00333153f9b0..c47973e53a8a7 100644
--- a/include/clang/Basic/OpenMPKinds.h
+++ b/include/clang/Basic/OpenMPKinds.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines some OpenMP-specific enums and functions.
+/// Defines some OpenMP-specific enums and functions.
///
//===----------------------------------------------------------------------===//
@@ -19,7 +19,7 @@
namespace clang {
-/// \brief OpenMP directives.
+/// OpenMP directives.
enum OpenMPDirectiveKind {
#define OPENMP_DIRECTIVE(Name) \
OMPD_##Name,
@@ -29,7 +29,7 @@ enum OpenMPDirectiveKind {
OMPD_unknown
};
-/// \brief OpenMP clauses.
+/// OpenMP clauses.
enum OpenMPClauseKind {
#define OPENMP_CLAUSE(Name, Class) \
OMPC_##Name,
@@ -39,7 +39,7 @@ enum OpenMPClauseKind {
OMPC_unknown
};
-/// \brief OpenMP attributes for 'default' clause.
+/// OpenMP attributes for 'default' clause.
enum OpenMPDefaultClauseKind {
#define OPENMP_DEFAULT_KIND(Name) \
OMPC_DEFAULT_##Name,
@@ -47,7 +47,7 @@ enum OpenMPDefaultClauseKind {
OMPC_DEFAULT_unknown
};
-/// \brief OpenMP attributes for 'proc_bind' clause.
+/// OpenMP attributes for 'proc_bind' clause.
enum OpenMPProcBindClauseKind {
#define OPENMP_PROC_BIND_KIND(Name) \
OMPC_PROC_BIND_##Name,
@@ -55,7 +55,7 @@ enum OpenMPProcBindClauseKind {
OMPC_PROC_BIND_unknown
};
-/// \brief OpenMP attributes for 'schedule' clause.
+/// OpenMP attributes for 'schedule' clause.
enum OpenMPScheduleClauseKind {
#define OPENMP_SCHEDULE_KIND(Name) \
OMPC_SCHEDULE_##Name,
@@ -63,7 +63,7 @@ enum OpenMPScheduleClauseKind {
OMPC_SCHEDULE_unknown
};
-/// \brief OpenMP modifiers for 'schedule' clause.
+/// OpenMP modifiers for 'schedule' clause.
enum OpenMPScheduleClauseModifier {
OMPC_SCHEDULE_MODIFIER_unknown = OMPC_SCHEDULE_unknown,
#define OPENMP_SCHEDULE_MODIFIER(Name) \
@@ -72,7 +72,7 @@ enum OpenMPScheduleClauseModifier {
OMPC_SCHEDULE_MODIFIER_last
};
-/// \brief OpenMP attributes for 'depend' clause.
+/// OpenMP attributes for 'depend' clause.
enum OpenMPDependClauseKind {
#define OPENMP_DEPEND_KIND(Name) \
OMPC_DEPEND_##Name,
@@ -80,7 +80,7 @@ enum OpenMPDependClauseKind {
OMPC_DEPEND_unknown
};
-/// \brief OpenMP attributes for 'linear' clause.
+/// OpenMP attributes for 'linear' clause.
enum OpenMPLinearClauseKind {
#define OPENMP_LINEAR_KIND(Name) \
OMPC_LINEAR_##Name,
@@ -88,7 +88,7 @@ enum OpenMPLinearClauseKind {
OMPC_LINEAR_unknown
};
-/// \brief OpenMP mapping kind for 'map' clause.
+/// OpenMP mapping kind for 'map' clause.
enum OpenMPMapClauseKind {
#define OPENMP_MAP_KIND(Name) \
OMPC_MAP_##Name,
@@ -96,14 +96,14 @@ enum OpenMPMapClauseKind {
OMPC_MAP_unknown
};
-/// \brief OpenMP attributes for 'dist_schedule' clause.
+/// OpenMP attributes for 'dist_schedule' clause.
enum OpenMPDistScheduleClauseKind {
#define OPENMP_DIST_SCHEDULE_KIND(Name) OMPC_DIST_SCHEDULE_##Name,
#include "clang/Basic/OpenMPKinds.def"
OMPC_DIST_SCHEDULE_unknown
};
-/// \brief OpenMP attributes for 'defaultmap' clause.
+/// OpenMP attributes for 'defaultmap' clause.
enum OpenMPDefaultmapClauseKind {
#define OPENMP_DEFAULTMAP_KIND(Name) \
OMPC_DEFAULTMAP_##Name,
@@ -111,7 +111,7 @@ enum OpenMPDefaultmapClauseKind {
OMPC_DEFAULTMAP_unknown
};
-/// \brief OpenMP modifiers for 'defaultmap' clause.
+/// OpenMP modifiers for 'defaultmap' clause.
enum OpenMPDefaultmapClauseModifier {
OMPC_DEFAULTMAP_MODIFIER_unknown = OMPC_DEFAULTMAP_unknown,
#define OPENMP_DEFAULTMAP_MODIFIER(Name) \
@@ -139,39 +139,39 @@ const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type);
bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
OpenMPClauseKind CKind);
-/// \brief Checks if the specified directive is a directive with an associated
+/// Checks if the specified directive is a directive with an associated
/// loop construct.
/// \param DKind Specified directive.
/// \return true - the directive is a loop-associated directive like 'omp simd'
/// or 'omp for' directive, otherwise - false.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind);
-/// \brief Checks if the specified directive is a worksharing directive.
+/// Checks if the specified directive is a worksharing directive.
/// \param DKind Specified directive.
/// \return true - the directive is a worksharing directive like 'omp for',
/// otherwise - false.
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind);
-/// \brief Checks if the specified directive is a taskloop directive.
+/// Checks if the specified directive is a taskloop directive.
/// \param DKind Specified directive.
/// \return true - the directive is a worksharing directive like 'omp taskloop',
/// otherwise - false.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind);
-/// \brief Checks if the specified directive is a parallel-kind directive.
+/// Checks if the specified directive is a parallel-kind directive.
/// \param DKind Specified directive.
/// \return true - the directive is a parallel-like directive like 'omp
/// parallel', otherwise - false.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
-/// \brief Checks if the specified directive is a target code offload directive.
+/// Checks if the specified directive is a target code offload directive.
/// \param DKind Specified directive.
/// \return true - the directive is a target code offload directive like
/// 'omp target', 'omp target parallel', 'omp target xxx'
/// otherwise - false.
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind);
-/// \brief Checks if the specified directive is a target data offload directive.
+/// Checks if the specified directive is a target data offload directive.
/// \param DKind Specified directive.
/// \return true - the directive is a target data offload directive like
/// 'omp target data', 'omp target update', 'omp target enter data',
@@ -193,13 +193,13 @@ bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind);
/// \return true - the directive is a teams-like directive, otherwise - false.
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind);
-/// \brief Checks if the specified directive is a simd directive.
+/// Checks if the specified directive is a simd directive.
/// \param DKind Specified directive.
/// \return true - the directive is a simd directive like 'omp simd',
/// otherwise - false.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind);
-/// \brief Checks if the specified directive is a distribute directive.
+/// Checks if the specified directive is a distribute directive.
/// \param DKind Specified directive.
/// \return true - the directive is a distribute-directive like 'omp
/// distribute',
@@ -214,13 +214,13 @@ bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind);
/// otherwise - false.
bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind);
-/// \brief Checks if the specified clause is one of private clauses like
+/// Checks if the specified clause is one of private clauses like
/// 'private', 'firstprivate', 'reduction' etc..
/// \param Kind Clause kind.
/// \return true - the clause is a private clause, otherwise - false.
bool isOpenMPPrivate(OpenMPClauseKind Kind);
-/// \brief Checks if the specified clause is one of threadprivate clauses like
+/// Checks if the specified clause is one of threadprivate clauses like
/// 'threadprivate', 'copyin' or 'copyprivate'.
/// \param Kind Clause kind.
/// \return true - the clause is a threadprivate clause, otherwise - false.
diff --git a/include/clang/Basic/OperatorKinds.h b/include/clang/Basic/OperatorKinds.h
index 7120baeef675a..b0064cfb4e5a7 100644
--- a/include/clang/Basic/OperatorKinds.h
+++ b/include/clang/Basic/OperatorKinds.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines an enumeration for C++ overloaded operators.
+/// Defines an enumeration for C++ overloaded operators.
///
//===----------------------------------------------------------------------===//
@@ -17,7 +17,7 @@
namespace clang {
-/// \brief Enumeration specifying the different kinds of C++ overloaded
+/// Enumeration specifying the different kinds of C++ overloaded
/// operators.
enum OverloadedOperatorKind : int {
OO_None, ///< Not an overloaded operator
@@ -27,7 +27,7 @@ enum OverloadedOperatorKind : int {
NUM_OVERLOADED_OPERATORS
};
-/// \brief Retrieve the spelling of the given overloaded operator, without
+/// Retrieve the spelling of the given overloaded operator, without
/// the preceding "operator" keyword.
const char *getOperatorSpelling(OverloadedOperatorKind Operator);
diff --git a/include/clang/Basic/OperatorPrecedence.h b/include/clang/Basic/OperatorPrecedence.h
index 94978f81e543a..4389e3bbd2576 100644
--- a/include/clang/Basic/OperatorPrecedence.h
+++ b/include/clang/Basic/OperatorPrecedence.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines and computes precedence levels for binary/ternary operators.
+/// Defines and computes precedence levels for binary/ternary operators.
///
//===----------------------------------------------------------------------===//
@@ -44,7 +44,7 @@ namespace prec {
};
}
-/// \brief Return the precedence of the specified binary operator token.
+/// Return the precedence of the specified binary operator token.
prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator,
bool CPlusPlus11);
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index b2f14afe5695a..9727af86f6494 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -1,4 +1,4 @@
-//===--- PartialDiagnostic.h - Diagnostic "closures" ------------*- C++ -*-===//
+//===- PartialDiagnostic.h - Diagnostic "closures" --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,25 +6,32 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
-/// \brief Implements a partial diagnostic that can be emitted anwyhere
+/// Implements a partial diagnostic that can be emitted anwyhere
/// in a DiagnosticBuilder stream.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H
#define LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include <cassert>
+#include <cstdint>
+#include <string>
+#include <type_traits>
+#include <utility>
namespace clang {
+class DeclContext;
+class IdentifierInfo;
+
class PartialDiagnostic {
public:
enum {
@@ -36,10 +43,8 @@ public:
};
struct Storage {
- Storage() : NumDiagArgs(0) { }
-
enum {
- /// \brief The maximum number of arguments we can hold. We
+ /// The maximum number of arguments we can hold. We
/// currently only support up to 10 arguments (%0-%9).
///
/// A single diagnostic with more than that almost certainly has to
@@ -47,33 +52,35 @@ public:
MaxArguments = PartialDiagnostic::MaxArguments
};
- /// \brief The number of entries in Arguments.
- unsigned char NumDiagArgs;
+ /// The number of entries in Arguments.
+ unsigned char NumDiagArgs = 0;
- /// \brief Specifies for each argument whether it is in DiagArgumentsStr
+ /// Specifies for each argument whether it is in DiagArgumentsStr
/// or in DiagArguments.
unsigned char DiagArgumentsKind[MaxArguments];
- /// \brief The values for the various substitution positions.
+ /// The values for the various substitution positions.
///
/// This is used when the argument is not an std::string. The specific value
/// is mangled into an intptr_t and the interpretation depends on exactly
/// what sort of argument kind it is.
intptr_t DiagArgumentsVal[MaxArguments];
- /// \brief The values for the various substitution positions that have
+ /// The values for the various substitution positions that have
/// string arguments.
std::string DiagArgumentsStr[MaxArguments];
- /// \brief The list of ranges added to this diagnostic.
+ /// The list of ranges added to this diagnostic.
SmallVector<CharSourceRange, 8> DiagRanges;
- /// \brief If valid, provides a hint with some code to insert, remove, or
+ /// If valid, provides a hint with some code to insert, remove, or
/// modify at a particular position.
SmallVector<FixItHint, 6> FixItHints;
+
+ Storage() = default;
};
- /// \brief An allocator for Storage objects, which uses a small cache to
+ /// An allocator for Storage objects, which uses a small cache to
/// objects, used to reduce malloc()/free() traffic for partial diagnostics.
class StorageAllocator {
static const unsigned NumCached = 16;
@@ -85,7 +92,7 @@ public:
StorageAllocator();
~StorageAllocator();
- /// \brief Allocate new storage.
+ /// Allocate new storage.
Storage *Allocate() {
if (NumFreeListEntries == 0)
return new Storage;
@@ -97,7 +104,7 @@ public:
return Result;
}
- /// \brief Free the given storage object.
+ /// Free the given storage object.
void Deallocate(Storage *S) {
if (S >= Cached && S <= Cached + NumCached) {
FreeList[NumFreeListEntries++] = S;
@@ -113,16 +120,16 @@ private:
// in the sense that its bits can be safely memcpy'ed and destructed
// in the new location.
- /// \brief The diagnostic ID.
- mutable unsigned DiagID;
+ /// The diagnostic ID.
+ mutable unsigned DiagID = 0;
- /// \brief Storage for args and ranges.
- mutable Storage *DiagStorage;
+ /// Storage for args and ranges.
+ mutable Storage *DiagStorage = nullptr;
- /// \brief Allocator used to allocate storage for this diagnostic.
- StorageAllocator *Allocator;
+ /// Allocator used to allocate storage for this diagnostic.
+ StorageAllocator *Allocator = nullptr;
- /// \brief Retrieve storage for this particular diagnostic.
+ /// Retrieve storage for this particular diagnostic.
Storage *getStorage() const {
if (DiagStorage)
return DiagStorage;
@@ -176,17 +183,16 @@ private:
public:
struct NullDiagnostic {};
- /// \brief Create a null partial diagnostic, which cannot carry a payload,
+
+ /// Create a null partial diagnostic, which cannot carry a payload,
/// and only exists to be swapped with a real partial diagnostic.
- PartialDiagnostic(NullDiagnostic)
- : DiagID(0), DiagStorage(nullptr), Allocator(nullptr) { }
+ PartialDiagnostic(NullDiagnostic) {}
PartialDiagnostic(unsigned DiagID, StorageAllocator &Allocator)
- : DiagID(DiagID), DiagStorage(nullptr), Allocator(&Allocator) { }
+ : DiagID(DiagID), Allocator(&Allocator) {}
PartialDiagnostic(const PartialDiagnostic &Other)
- : DiagID(Other.DiagID), DiagStorage(nullptr), Allocator(Other.Allocator)
- {
+ : DiagID(Other.DiagID), Allocator(Other.Allocator) {
if (Other.DiagStorage) {
DiagStorage = getStorage();
*DiagStorage = *Other.DiagStorage;
@@ -194,22 +200,20 @@ public:
}
PartialDiagnostic(PartialDiagnostic &&Other)
- : DiagID(Other.DiagID), DiagStorage(Other.DiagStorage),
- Allocator(Other.Allocator) {
+ : DiagID(Other.DiagID), DiagStorage(Other.DiagStorage),
+ Allocator(Other.Allocator) {
Other.DiagStorage = nullptr;
}
PartialDiagnostic(const PartialDiagnostic &Other, Storage *DiagStorage)
- : DiagID(Other.DiagID), DiagStorage(DiagStorage),
- Allocator(reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
- {
+ : DiagID(Other.DiagID), DiagStorage(DiagStorage),
+ Allocator(reinterpret_cast<StorageAllocator *>(~uintptr_t(0))) {
if (Other.DiagStorage)
*this->DiagStorage = *Other.DiagStorage;
}
PartialDiagnostic(const Diagnostic &Other, StorageAllocator &Allocator)
- : DiagID(Other.getID()), DiagStorage(nullptr), Allocator(&Allocator)
- {
+ : DiagID(Other.getID()), Allocator(&Allocator) {
// Copy arguments.
for (unsigned I = 0, N = Other.getNumArgs(); I != N; ++I) {
if (Other.getArgKind(I) == DiagnosticsEngine::ak_std_string)
@@ -320,7 +324,7 @@ public:
Diags.Clear();
}
- /// \brief Clear out this partial diagnostic, giving it a new diagnostic ID
+ /// Clear out this partial diagnostic, giving it a new diagnostic ID
/// and removing all of its arguments, ranges, and fix-it hints.
void Reset(unsigned DiagID = 0) {
this->DiagID = DiagID;
@@ -402,7 +406,6 @@ public:
PD.AddFixItHint(Hint);
return PD;
}
-
};
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
@@ -411,9 +414,10 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
return DB;
}
-/// \brief A partial diagnostic along with the source location where this
+/// A partial diagnostic along with the source location where this
/// diagnostic occurs.
-typedef std::pair<SourceLocation, PartialDiagnostic> PartialDiagnosticAt;
+using PartialDiagnosticAt = std::pair<SourceLocation, PartialDiagnostic>;
+
+} // namespace clang
-} // end namespace clang
-#endif
+#endif // LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H
diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h
index 61de82450cf78..be92bbfde1853 100644
--- a/include/clang/Basic/PlistSupport.h
+++ b/include/clang/Basic/PlistSupport.h
@@ -1,4 +1,4 @@
-//===---------- PlistSupport.h - Plist Output Utilities ---------*- C++ -*-===//
+//===- PlistSupport.h - Plist Output Utilities ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,12 +10,20 @@
#ifndef LLVM_CLANG_BASIC_PLISTSUPPORT_H
#define LLVM_CLANG_BASIC_PLISTSUPPORT_H
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdint>
namespace clang {
namespace markup {
-typedef llvm::DenseMap<FileID, unsigned> FIDMap;
+
+using FIDMap = llvm::DenseMap<FileID, unsigned>;
inline void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
const SourceManager &SM, SourceLocation L) {
@@ -112,7 +120,8 @@ inline void EmitRange(raw_ostream &o, const SourceManager &SM,
EmitLocation(o, SM, R.getEnd(), FM, indent + 1);
Indent(o, indent) << "</array>\n";
}
-}
-}
-#endif
+} // namespace markup
+} // namespace clang
+
+#endif // LLVM_CLANG_BASIC_PLISTSUPPORT_H
diff --git a/include/clang/Basic/PrettyStackTrace.h b/include/clang/Basic/PrettyStackTrace.h
index 6badae5c03496..e652f52055d6a 100644
--- a/include/clang/Basic/PrettyStackTrace.h
+++ b/include/clang/Basic/PrettyStackTrace.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the PrettyStackTraceEntry class, which is used to make
+/// Defines the PrettyStackTraceEntry class, which is used to make
/// crashes give more contextual information about what the program was doing
/// when it crashed.
///
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
index 30d5cc8166dc6..5a36822a63035 100644
--- a/include/clang/Basic/Sanitizers.def
+++ b/include/clang/Basic/Sanitizers.def
@@ -44,8 +44,12 @@ SANITIZER("address", Address)
// Kernel AddressSanitizer (KASan)
SANITIZER("kernel-address", KernelAddress)
+// Hardware-assisted AddressSanitizer
SANITIZER("hwaddress", HWAddress)
+// Kernel Hardware-assisted AddressSanitizer (KHWASan)
+SANITIZER("kernel-hwaddress", KernelHWAddress)
+
// MemorySanitizer
SANITIZER("memory", Memory)
@@ -100,16 +104,20 @@ SANITIZER("dataflow", DataFlow)
SANITIZER("cfi-cast-strict", CFICastStrict)
SANITIZER("cfi-derived-cast", CFIDerivedCast)
SANITIZER("cfi-icall", CFIICall)
+SANITIZER("cfi-mfcall", CFIMFCall)
SANITIZER("cfi-unrelated-cast", CFIUnrelatedCast)
SANITIZER("cfi-nvcall", CFINVCall)
SANITIZER("cfi-vcall", CFIVCall)
SANITIZER_GROUP("cfi", CFI,
- CFIDerivedCast | CFIICall | CFIUnrelatedCast | CFINVCall |
- CFIVCall)
+ CFIDerivedCast | CFIICall | CFIMFCall | CFIUnrelatedCast |
+ CFINVCall | CFIVCall)
// Safe Stack
SANITIZER("safe-stack", SafeStack)
+// Shadow Call Stack
+SANITIZER("shadow-call-stack", ShadowCallStack)
+
// -fsanitize=undefined includes all the sanitizers which have low overhead, no
// ABI or address space layout implications, and only catch undefined behavior.
SANITIZER_GROUP("undefined", Undefined,
diff --git a/include/clang/Basic/Sanitizers.h b/include/clang/Basic/Sanitizers.h
index 1b936c7d115cf..469d9e2e95917 100644
--- a/include/clang/Basic/Sanitizers.h
+++ b/include/clang/Basic/Sanitizers.h
@@ -1,4 +1,4 @@
-//===--- Sanitizers.h - C Language Family Language Options ------*- C++ -*-===//
+//===- Sanitizers.h - C Language Family Language Options --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
-/// \brief Defines the clang::SanitizerKind enum.
-///
+/// Defines the clang::SanitizerKind enum.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_SANITIZERS_H
@@ -18,10 +18,12 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <cstdint>
namespace clang {
-typedef uint64_t SanitizerMask;
+using SanitizerMask = uint64_t;
namespace SanitizerKind {
@@ -43,19 +45,19 @@ enum SanitizerOrdinal : uint64_t {
const SanitizerMask ID##Group = 1ULL << SO_##ID##Group;
#include "clang/Basic/Sanitizers.def"
-}
+} // namespace SanitizerKind
struct SanitizerSet {
- /// \brief Check if a certain (single) sanitizer is enabled.
+ /// Check if a certain (single) sanitizer is enabled.
bool has(SanitizerMask K) const {
assert(llvm::isPowerOf2_64(K));
return Mask & K;
}
- /// \brief Check if one or more sanitizers are enabled.
+ /// Check if one or more sanitizers are enabled.
bool hasOneOf(SanitizerMask K) const { return Mask & K; }
- /// \brief Enable or disable a certain (single) sanitizer.
+ /// Enable or disable a certain (single) sanitizer.
void set(SanitizerMask K, bool Value) {
assert(llvm::isPowerOf2_64(K));
Mask = Value ? (Mask | K) : (Mask & ~K);
@@ -64,10 +66,10 @@ struct SanitizerSet {
/// Disable the sanitizers specified in \p K.
void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; }
- /// \brief Returns true if at least one sanitizer is enabled.
+ /// Returns true if at least one sanitizer is enabled.
bool empty() const { return Mask == 0; }
- /// \brief Bitmask of enabled sanitizers.
+ /// Bitmask of enabled sanitizers.
SanitizerMask Mask = 0;
};
@@ -85,6 +87,6 @@ inline SanitizerMask getPPTransparentSanitizers() {
SanitizerKind::Nullability | SanitizerKind::Undefined;
}
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_BASIC_SANITIZERS_H
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 7418b50f9d83b..f174f83abf4a0 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -1,4 +1,4 @@
-//===--- SourceLocation.h - Compact identifier for Source Files -*- C++ -*-===//
+//===- SourceLocation.h - Compact identifier for Source Files ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,38 +6,39 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
-/// \brief Defines the clang::SourceLocation class and associated facilities.
-///
+/// Defines the clang::SourceLocation class and associated facilities.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_SOURCELOCATION_H
#define LLVM_CLANG_BASIC_SOURCELOCATION_H
#include "clang/Basic/LLVM.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
-#include <functional>
+#include <cstdint>
#include <string>
#include <utility>
namespace llvm {
- class MemoryBuffer;
- template <typename T> struct DenseMapInfo;
- template <typename T> struct isPodLike;
-}
+
+template <typename T> struct DenseMapInfo;
+template <typename T> struct isPodLike;
+
+} // namespace llvm
namespace clang {
class SourceManager;
-/// \brief An opaque identifier used by SourceManager which refers to a
+/// An opaque identifier used by SourceManager which refers to a
/// source file (MemoryBuffer) along with its \#include path and \#line data.
///
class FileID {
- /// \brief A mostly-opaque identifier, where 0 is "invalid", >0 is
+ /// A mostly-opaque identifier, where 0 is "invalid", >0 is
/// this module, and <-1 is something loaded from another module.
int ID = 0;
@@ -56,20 +57,20 @@ public:
unsigned getHashValue() const { return static_cast<unsigned>(ID); }
private:
- friend class SourceManager;
friend class ASTWriter;
friend class ASTReader;
+ friend class SourceManager;
static FileID get(int V) {
FileID F;
F.ID = V;
return F;
}
+
int getOpaqueValue() const { return ID; }
};
-
-/// \brief Encodes a location in the source. The SourceManager can decode this
+/// Encodes a location in the source. The SourceManager can decode this
/// to get at the full include stack, line and column information.
///
/// Technically, a source location is simply an offset into the manager's view
@@ -85,10 +86,12 @@ private:
///
/// It is important that this type remains small. It is currently 32 bits wide.
class SourceLocation {
- unsigned ID = 0;
- friend class SourceManager;
friend class ASTReader;
friend class ASTWriter;
+ friend class SourceManager;
+
+ unsigned ID = 0;
+
enum : unsigned {
MacroIDBit = 1U << 31
};
@@ -97,7 +100,7 @@ public:
bool isFileID() const { return (ID & MacroIDBit) == 0; }
bool isMacroID() const { return (ID & MacroIDBit) != 0; }
- /// \brief Return true if this is a valid SourceLocation object.
+ /// Return true if this is a valid SourceLocation object.
///
/// Invalid SourceLocations are often used when events have no corresponding
/// location in the source (e.g. a diagnostic is required for a command line
@@ -106,7 +109,7 @@ public:
bool isInvalid() const { return ID == 0; }
private:
- /// \brief Return the offset into the manager's global input view.
+ /// Return the offset into the manager's global input view.
unsigned getOffset() const {
return ID & ~MacroIDBit;
}
@@ -124,9 +127,9 @@ private:
L.ID = MacroIDBit | ID;
return L;
}
-public:
- /// \brief Return a source location with the specified offset from this
+public:
+ /// Return a source location with the specified offset from this
/// SourceLocation.
SourceLocation getLocWithOffset(int Offset) const {
assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow");
@@ -135,14 +138,14 @@ public:
return L;
}
- /// \brief When a SourceLocation itself cannot be used, this returns
+ /// When a SourceLocation itself cannot be used, this returns
/// an (opaque) 32-bit integer encoding for it.
///
/// This should only be passed to SourceLocation::getFromRawEncoding, it
/// should not be inspected directly.
unsigned getRawEncoding() const { return ID; }
- /// \brief Turn a raw encoding of a SourceLocation object into
+ /// Turn a raw encoding of a SourceLocation object into
/// a real SourceLocation.
///
/// \see getRawEncoding.
@@ -152,7 +155,7 @@ public:
return X;
}
- /// \brief When a SourceLocation itself cannot be used, this returns
+ /// When a SourceLocation itself cannot be used, this returns
/// an (opaque) pointer encoding for it.
///
/// This should only be passed to SourceLocation::getFromPtrEncoding, it
@@ -163,7 +166,7 @@ public:
return (void*)(uintptr_t)getRawEncoding();
}
- /// \brief Turn a pointer encoding of a SourceLocation object back
+ /// Turn a pointer encoding of a SourceLocation object back
/// into a real SourceLocation.
static SourceLocation getFromPtrEncoding(const void *Encoding) {
return getFromRawEncoding((unsigned)(uintptr_t)Encoding);
@@ -191,7 +194,7 @@ inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
return LHS.getRawEncoding() < RHS.getRawEncoding();
}
-/// \brief A trivial tuple used to represent a source range.
+/// A trivial tuple used to represent a source range.
class SourceRange {
SourceLocation B;
SourceLocation E;
@@ -219,7 +222,7 @@ public:
}
};
-/// \brief Represents a character-granular source range.
+/// Represents a character-granular source range.
///
/// The underlying SourceRange can either specify the starting/ending character
/// of the range, or it can specify the start of the range and the start of the
@@ -245,11 +248,12 @@ public:
static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E) {
return getTokenRange(SourceRange(B, E));
}
+
static CharSourceRange getCharRange(SourceLocation B, SourceLocation E) {
return getCharRange(SourceRange(B, E));
}
- /// \brief Return true if the end of this range specifies the start of
+ /// Return true if the end of this range specifies the start of
/// the last token. Return false if the end of this range specifies the last
/// character in the range.
bool isTokenRange() const { return IsTokenRange; }
@@ -261,12 +265,13 @@ public:
void setBegin(SourceLocation b) { Range.setBegin(b); }
void setEnd(SourceLocation e) { Range.setEnd(e); }
+ void setTokenRange(bool TR) { IsTokenRange = TR; }
bool isValid() const { return Range.isValid(); }
bool isInvalid() const { return !isValid(); }
};
-/// \brief Represents an unpacked "presumed" location which can be presented
+/// Represents an unpacked "presumed" location which can be presented
/// to the user.
///
/// A 'presumed' location can be modified by \#line and GNU line marker
@@ -274,23 +279,23 @@ public:
///
/// You can get a PresumedLoc from a SourceLocation with SourceManager.
class PresumedLoc {
- const char *Filename;
+ const char *Filename = nullptr;
unsigned Line, Col;
SourceLocation IncludeLoc;
public:
- PresumedLoc() : Filename(nullptr) {}
+ PresumedLoc() = default;
PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
: Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {}
- /// \brief Return true if this object is invalid or uninitialized.
+ /// Return true if this object is invalid or uninitialized.
///
/// This occurs when created with invalid source locations or when walking
/// off the top of a \#include stack.
bool isInvalid() const { return Filename == nullptr; }
bool isValid() const { return Filename != nullptr; }
- /// \brief Return the presumed filename of this location.
+ /// Return the presumed filename of this location.
///
/// This can be affected by \#line etc.
const char *getFilename() const {
@@ -298,7 +303,7 @@ public:
return Filename;
}
- /// \brief Return the presumed line number of this location.
+ /// Return the presumed line number of this location.
///
/// This can be affected by \#line etc.
unsigned getLine() const {
@@ -306,7 +311,7 @@ public:
return Line;
}
- /// \brief Return the presumed column number of this location.
+ /// Return the presumed column number of this location.
///
/// This cannot be affected by \#line, but is packaged here for convenience.
unsigned getColumn() const {
@@ -314,7 +319,7 @@ public:
return Col;
}
- /// \brief Return the presumed include location of this location.
+ /// Return the presumed include location of this location.
///
/// This can be affected by GNU linemarker directives.
SourceLocation getIncludeLoc() const {
@@ -325,18 +330,18 @@ public:
class FileEntry;
-/// \brief A SourceLocation and its associated SourceManager.
+/// A SourceLocation and its associated SourceManager.
///
/// This is useful for argument passing to functions that expect both objects.
class FullSourceLoc : public SourceLocation {
const SourceManager *SrcMgr = nullptr;
public:
- /// \brief Creates a FullSourceLoc where isValid() returns \c false.
+ /// Creates a FullSourceLoc where isValid() returns \c false.
FullSourceLoc() = default;
explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
- : SourceLocation(Loc), SrcMgr(&SM) {}
+ : SourceLocation(Loc), SrcMgr(&SM) {}
bool hasManager() const {
bool hasSrcMgr = SrcMgr != nullptr;
@@ -355,7 +360,6 @@ public:
FullSourceLoc getExpansionLoc() const;
FullSourceLoc getSpellingLoc() const;
FullSourceLoc getFileLoc() const;
- std::pair<FullSourceLoc, FullSourceLoc> getImmediateExpansionRange() const;
PresumedLoc getPresumedLoc(bool UseLineDirectives = true) const;
bool isMacroArgExpansion(FullSourceLoc *StartLoc = nullptr) const;
FullSourceLoc getImmediateMacroCallerLoc() const;
@@ -373,15 +377,13 @@ public:
unsigned getLineNumber(bool *Invalid = nullptr) const;
unsigned getColumnNumber(bool *Invalid = nullptr) const;
- std::pair<FullSourceLoc, FullSourceLoc> getExpansionRange() const;
-
const FileEntry *getFileEntry() const;
- /// \brief Return a StringRef to the source buffer data for the
+ /// Return a StringRef to the source buffer data for the
/// specified FileID.
StringRef getBufferData(bool *Invalid = nullptr) const;
- /// \brief Decompose the specified location into a raw FileID + Offset pair.
+ /// Decompose the specified location into a raw FileID + Offset pair.
///
/// The first element is the FileID, the second is the offset from the
/// start of the buffer of the location.
@@ -389,12 +391,12 @@ public:
bool isInSystemHeader() const;
- /// \brief Determines the order of 2 source locations in the translation unit.
+ /// Determines the order of 2 source locations in the translation unit.
///
/// \returns true if this source location comes before 'Loc', false otherwise.
bool isBeforeInTranslationUnitThan(SourceLocation Loc) const;
- /// \brief Determines the order of 2 source locations in the translation unit.
+ /// Determines the order of 2 source locations in the translation unit.
///
/// \returns true if this source location comes before 'Loc', false otherwise.
bool isBeforeInTranslationUnitThan(FullSourceLoc Loc) const {
@@ -403,44 +405,43 @@ public:
return isBeforeInTranslationUnitThan((SourceLocation)Loc);
}
- /// \brief Comparison function class, useful for sorting FullSourceLocs.
+ /// Comparison function class, useful for sorting FullSourceLocs.
struct BeforeThanCompare {
bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
return lhs.isBeforeInTranslationUnitThan(rhs);
}
};
- /// \brief Prints information about this FullSourceLoc to stderr.
+ /// Prints information about this FullSourceLoc to stderr.
///
/// This is useful for debugging.
void dump() const;
- friend inline bool
+ friend bool
operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
return LHS.getRawEncoding() == RHS.getRawEncoding() &&
LHS.SrcMgr == RHS.SrcMgr;
}
- friend inline bool
+ friend bool
operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
return !(LHS == RHS);
}
-
};
-
-
-} // end namespace clang
+} // namespace clang
namespace llvm {
+
/// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
/// DenseSets.
template <>
struct DenseMapInfo<clang::FileID> {
- static inline clang::FileID getEmptyKey() {
- return clang::FileID();
+ static clang::FileID getEmptyKey() {
+ return {};
}
- static inline clang::FileID getTombstoneKey() {
+
+ static clang::FileID getTombstoneKey() {
return clang::FileID::getSentinel();
}
@@ -461,15 +462,17 @@ namespace llvm {
// Teach SmallPtrSet how to handle SourceLocation.
template<>
struct PointerLikeTypeTraits<clang::SourceLocation> {
- static inline void *getAsVoidPointer(clang::SourceLocation L) {
+ enum { NumLowBitsAvailable = 0 };
+
+ static void *getAsVoidPointer(clang::SourceLocation L) {
return L.getPtrEncoding();
}
- static inline clang::SourceLocation getFromVoidPointer(void *P) {
+
+ static clang::SourceLocation getFromVoidPointer(void *P) {
return clang::SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)P);
}
- enum { NumLowBitsAvailable = 0 };
};
-} // end namespace llvm
+} // namespace llvm
-#endif
+#endif // LLVM_CLANG_BASIC_SOURCELOCATION_H
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 397ad2e77fb5e..99c36f4cdfcc8 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Defines the SourceManager interface.
+/// Defines the SourceManager interface.
///
/// There are three different types of locations in a %file: a spelling
/// location, an expansion location, and a presumed location.
@@ -35,6 +35,7 @@
#ifndef LLVM_CLANG_BASIC_SOURCEMANAGER_H
#define LLVM_CLANG_BASIC_SOURCEMANAGER_H
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
@@ -60,15 +61,14 @@ namespace clang {
class ASTReader;
class ASTWriter;
-class DiagnosticsEngine;
class LineTableInfo;
class SourceManager;
-/// \brief Public enums and private classes that are part of the
+/// Public enums and private classes that are part of the
/// SourceManager implementation.
namespace SrcMgr {
- /// \brief Indicates whether a file or directory holds normal user code,
+ /// Indicates whether a file or directory holds normal user code,
/// system code, or system code which is implicitly 'extern "C"' in C++ mode.
///
/// Entire directories can be tagged with this (this is maintained by
@@ -89,19 +89,19 @@ namespace SrcMgr {
return CK == C_User_ModuleMap || CK == C_System_ModuleMap;
}
- /// \brief One instance of this struct is kept for every file loaded or used.
+ /// One instance of this struct is kept for every file loaded or used.
///
/// This object owns the MemoryBuffer object.
- class LLVM_ALIGNAS(8) ContentCache {
+ class alignas(8) ContentCache {
enum CCFlags {
- /// \brief Whether the buffer is invalid.
+ /// Whether the buffer is invalid.
InvalidFlag = 0x01,
- /// \brief Whether the buffer should not be freed on destruction.
+ /// Whether the buffer should not be freed on destruction.
DoNotFreeFlag = 0x02
};
- /// \brief The actual buffer containing the characters from the input
+ /// The actual buffer containing the characters from the input
/// file.
///
/// This is owned by the ContentCache object. The bits indicate
@@ -109,7 +109,7 @@ namespace SrcMgr {
mutable llvm::PointerIntPair<llvm::MemoryBuffer *, 2> Buffer;
public:
- /// \brief Reference to the file entry representing this ContentCache.
+ /// Reference to the file entry representing this ContentCache.
///
/// This reference does not own the FileEntry object.
///
@@ -117,35 +117,35 @@ namespace SrcMgr {
/// an imaginary text buffer.
const FileEntry *OrigEntry;
- /// \brief References the file which the contents were actually loaded from.
+ /// References the file which the contents were actually loaded from.
///
/// Can be different from 'Entry' if we overridden the contents of one file
/// with the contents of another file.
const FileEntry *ContentsEntry;
- /// \brief A bump pointer allocated array of offsets for each source line.
+ /// A bump pointer allocated array of offsets for each source line.
///
/// This is lazily computed. This is owned by the SourceManager
/// BumpPointerAllocator object.
unsigned *SourceLineCache = nullptr;
- /// \brief The number of lines in this ContentCache.
+ /// The number of lines in this ContentCache.
///
/// This is only valid if SourceLineCache is non-null.
unsigned NumLines = 0;
- /// \brief Indicates whether the buffer itself was provided to override
+ /// Indicates whether the buffer itself was provided to override
/// the actual file contents.
///
/// When true, the original entry may be a virtual file that does not
/// exist.
unsigned BufferOverridden : 1;
- /// \brief True if this content cache was initially created for a source
+ /// True if this content cache was initially created for a source
/// file considered as a system one.
unsigned IsSystemFile : 1;
- /// \brief True if this file may be transient, that is, if it might not
+ /// True if this file may be transient, that is, if it might not
/// exist at some later point in time when this content entry is used,
/// after serialization and deserialization.
unsigned IsTransient : 1;
@@ -176,7 +176,7 @@ namespace SrcMgr {
~ContentCache();
- /// \brief Returns the memory buffer for the associated content.
+ /// Returns the memory buffer for the associated content.
///
/// \param Diag Object through which diagnostics will be emitted if the
/// buffer cannot be retrieved.
@@ -190,7 +190,7 @@ namespace SrcMgr {
SourceLocation Loc = SourceLocation(),
bool *Invalid = nullptr) const;
- /// \brief Returns the size of the content encapsulated by this
+ /// Returns the size of the content encapsulated by this
/// ContentCache.
///
/// This can be the size of the source file or the size of an
@@ -198,7 +198,7 @@ namespace SrcMgr {
/// file this size is retrieved from the file's FileEntry.
unsigned getSize() const;
- /// \brief Returns the number of bytes actually mapped for this
+ /// Returns the number of bytes actually mapped for this
/// ContentCache.
///
/// This can be 0 if the MemBuffer was not actually expanded.
@@ -208,20 +208,20 @@ namespace SrcMgr {
/// this content cache. This is used for performance analysis.
llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const;
- /// \brief Get the underlying buffer, returning NULL if the buffer is not
+ /// Get the underlying buffer, returning NULL if the buffer is not
/// yet available.
llvm::MemoryBuffer *getRawBuffer() const { return Buffer.getPointer(); }
- /// \brief Replace the existing buffer (which will be deleted)
+ /// Replace the existing buffer (which will be deleted)
/// with the given buffer.
void replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree = false);
- /// \brief Determine whether the buffer itself is invalid.
+ /// Determine whether the buffer itself is invalid.
bool isBufferInvalid() const {
return Buffer.getInt() & InvalidFlag;
}
- /// \brief Determine whether the buffer should be freed.
+ /// Determine whether the buffer should be freed.
bool shouldFreeBuffer() const {
return (Buffer.getInt() & DoNotFreeFlag) == 0;
}
@@ -232,7 +232,7 @@ namespace SrcMgr {
static_assert(alignof(ContentCache) >= 8,
"ContentCache must be 8-byte aligned.");
- /// \brief Information about a FileID, basically just the logical file
+ /// Information about a FileID, basically just the logical file
/// that it represents and include stack information.
///
/// Each FileInfo has include stack information, indicating where it came
@@ -246,26 +246,26 @@ namespace SrcMgr {
friend class clang::ASTWriter;
friend class clang::ASTReader;
- /// \brief The location of the \#include that brought in this file.
+ /// The location of the \#include that brought in this file.
///
/// This is an invalid SLOC for the main file (top of the \#include chain).
unsigned IncludeLoc; // Really a SourceLocation
- /// \brief Number of FileIDs (files and macros) that were created during
+ /// Number of FileIDs (files and macros) that were created during
/// preprocessing of this \#include, including this SLocEntry.
///
/// Zero means the preprocessor didn't provide such info for this SLocEntry.
unsigned NumCreatedFIDs : 31;
- /// \brief Whether this FileInfo has any \#line directives.
+ /// Whether this FileInfo has any \#line directives.
unsigned HasLineDirectives : 1;
- /// \brief The content cache and the characteristic of the file.
+ /// The content cache and the characteristic of the file.
llvm::PointerIntPair<const ContentCache*, 3, CharacteristicKind>
ContentAndKind;
public:
- /// \brief Return a FileInfo object.
+ /// Return a FileInfo object.
static FileInfo get(SourceLocation IL, const ContentCache *Con,
CharacteristicKind FileCharacter) {
FileInfo X;
@@ -285,28 +285,28 @@ namespace SrcMgr {
return ContentAndKind.getPointer();
}
- /// \brief Return whether this is a system header or not.
+ /// Return whether this is a system header or not.
CharacteristicKind getFileCharacteristic() const {
return ContentAndKind.getInt();
}
- /// \brief Return true if this FileID has \#line directives in it.
+ /// Return true if this FileID has \#line directives in it.
bool hasLineDirectives() const { return HasLineDirectives; }
- /// \brief Set the flag that indicates that this FileID has
+ /// Set the flag that indicates that this FileID has
/// line table entries associated with it.
void setHasLineDirectives() {
HasLineDirectives = true;
}
};
- /// \brief Each ExpansionInfo encodes the expansion location - where
+ /// Each ExpansionInfo encodes the expansion location - where
/// the token was ultimately expanded, and the SpellingLoc - where the actual
/// character data for the token came from.
class ExpansionInfo {
// Really these are all SourceLocations.
- /// \brief Where the spelling for the token can be found.
+ /// Where the spelling for the token can be found.
unsigned SpellingLoc;
/// In a macro expansion, ExpansionLocStart and ExpansionLocEnd
@@ -317,9 +317,13 @@ namespace SrcMgr {
/// invalid location.
unsigned ExpansionLocStart, ExpansionLocEnd;
+ /// Whether the expansion range is a token range.
+ bool ExpansionIsTokenRange;
+
public:
SourceLocation getSpellingLoc() const {
- return SourceLocation::getFromRawEncoding(SpellingLoc);
+ SourceLocation SpellLoc = SourceLocation::getFromRawEncoding(SpellingLoc);
+ return SpellLoc.isInvalid() ? getExpansionLocStart() : SpellLoc;
}
SourceLocation getExpansionLocStart() const {
@@ -332,8 +336,14 @@ namespace SrcMgr {
return EndLoc.isInvalid() ? getExpansionLocStart() : EndLoc;
}
- std::pair<SourceLocation,SourceLocation> getExpansionLocRange() const {
- return std::make_pair(getExpansionLocStart(), getExpansionLocEnd());
+ bool isExpansionTokenRange() const {
+ return ExpansionIsTokenRange;
+ }
+
+ CharSourceRange getExpansionLocRange() const {
+ return CharSourceRange(
+ SourceRange(getExpansionLocStart(), getExpansionLocEnd()),
+ isExpansionTokenRange());
}
bool isMacroArgExpansion() const {
@@ -352,22 +362,24 @@ namespace SrcMgr {
getExpansionLocStart() != getExpansionLocEnd();
}
- /// \brief Return a ExpansionInfo for an expansion.
+ /// Return a ExpansionInfo for an expansion.
///
/// Start and End specify the expansion range (where the macro is
/// expanded), and SpellingLoc specifies the spelling location (where
/// the characters from the token come from). All three can refer to
/// normal File SLocs or expansion locations.
static ExpansionInfo create(SourceLocation SpellingLoc,
- SourceLocation Start, SourceLocation End) {
+ SourceLocation Start, SourceLocation End,
+ bool ExpansionIsTokenRange = true) {
ExpansionInfo X;
X.SpellingLoc = SpellingLoc.getRawEncoding();
X.ExpansionLocStart = Start.getRawEncoding();
X.ExpansionLocEnd = End.getRawEncoding();
+ X.ExpansionIsTokenRange = ExpansionIsTokenRange;
return X;
}
- /// \brief Return a special ExpansionInfo for the expansion of
+ /// Return a special ExpansionInfo for the expansion of
/// a macro argument into a function-like macro's body.
///
/// ExpansionLoc specifies the expansion location (where the macro is
@@ -389,13 +401,24 @@ namespace SrcMgr {
static ExpansionInfo createForMacroArg(SourceLocation SpellingLoc,
SourceLocation ExpansionLoc) {
// We store an intentionally invalid source location for the end of the
- // expansion range to mark that this is a macro argument ion rather than
- // a normal one.
+ // expansion range to mark that this is a macro argument location rather
+ // than a normal one.
return create(SpellingLoc, ExpansionLoc, SourceLocation());
}
+
+ /// Return a special ExpansionInfo representing a token that ends
+ /// prematurely. This is used to model a '>>' token that has been split
+ /// into '>' tokens and similar cases. Unlike for the other forms of
+ /// expansion, the expansion range in this case is a character range, not
+ /// a token range.
+ static ExpansionInfo createForTokenSplit(SourceLocation SpellingLoc,
+ SourceLocation Start,
+ SourceLocation End) {
+ return create(SpellingLoc, Start, End, false);
+ }
};
- /// \brief This is a discriminated union of FileInfo and ExpansionInfo.
+ /// This is a discriminated union of FileInfo and ExpansionInfo.
///
/// SourceManager keeps an array of these objects, and they are uniquely
/// identified by the FileID datatype.
@@ -446,44 +469,44 @@ namespace SrcMgr {
} // namespace SrcMgr
-/// \brief External source of source location entries.
+/// External source of source location entries.
class ExternalSLocEntrySource {
public:
virtual ~ExternalSLocEntrySource();
- /// \brief Read the source location entry with index ID, which will always be
+ /// Read the source location entry with index ID, which will always be
/// less than -1.
///
/// \returns true if an error occurred that prevented the source-location
/// entry from being loaded.
virtual bool ReadSLocEntry(int ID) = 0;
- /// \brief Retrieve the module import location and name for the given ID, if
+ /// Retrieve the module import location and name for the given ID, if
/// in fact it was loaded from a module (rather than, say, a precompiled
/// header).
virtual std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID) = 0;
};
-/// \brief Holds the cache used by isBeforeInTranslationUnit.
+/// Holds the cache used by isBeforeInTranslationUnit.
///
/// The cache structure is complex enough to be worth breaking out of
/// SourceManager.
class InBeforeInTUCacheEntry {
- /// \brief The FileID's of the cached query.
+ /// The FileID's of the cached query.
///
/// If these match up with a subsequent query, the result can be reused.
FileID LQueryFID, RQueryFID;
- /// \brief True if LQueryFID was created before RQueryFID.
+ /// True if LQueryFID was created before RQueryFID.
///
/// This is used to compare macro expansion locations.
bool IsLQFIDBeforeRQFID;
- /// \brief The file found in common between the two \#include traces, i.e.,
+ /// The file found in common between the two \#include traces, i.e.,
/// the nearest common ancestor of the \#include tree.
FileID CommonFID;
- /// \brief The offset of the previous query in CommonFID.
+ /// The offset of the previous query in CommonFID.
///
/// Usually, this represents the location of the \#include for QueryFID, but
/// if LQueryFID is a parent of RQueryFID (or vice versa) then these can be a
@@ -491,7 +514,7 @@ class InBeforeInTUCacheEntry {
unsigned LCommonOffset, RCommonOffset;
public:
- /// \brief Return true if the currently cached values match up with
+ /// Return true if the currently cached values match up with
/// the specified LHS/RHS query.
///
/// If not, we can't use the cache.
@@ -499,7 +522,7 @@ public:
return LQueryFID == LHS && RQueryFID == RHS;
}
- /// \brief If the cache is valid, compute the result given the
+ /// If the cache is valid, compute the result given the
/// specified offsets in the LHS/RHS FileID's.
bool getCachedResult(unsigned LOffset, unsigned ROffset) const {
// If one of the query files is the common file, use the offset. Otherwise,
@@ -518,7 +541,7 @@ public:
return LOffset < ROffset;
}
- /// \brief Set up a new query.
+ /// Set up a new query.
void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID) {
assert(LHS != RHS);
LQueryFID = LHS;
@@ -539,12 +562,12 @@ public:
}
};
-/// \brief The stack used when building modules on demand, which is used
+/// The stack used when building modules on demand, which is used
/// to provide a link between the source managers of the different compiler
/// instances.
using ModuleBuildStack = ArrayRef<std::pair<std::string, FullSourceLoc>>;
-/// \brief This class handles loading and caching of source files into memory.
+/// This class handles loading and caching of source files into memory.
///
/// This object owns the MemoryBuffer objects for all of the loaded
/// files and assigns unique FileID's for each unique \#include chain.
@@ -557,14 +580,14 @@ using ModuleBuildStack = ArrayRef<std::pair<std::string, FullSourceLoc>>;
/// where the expanded token came from and the expansion location specifies
/// where it was expanded.
class SourceManager : public RefCountedBase<SourceManager> {
- /// \brief DiagnosticsEngine object.
+ /// DiagnosticsEngine object.
DiagnosticsEngine &Diag;
FileManager &FileMgr;
mutable llvm::BumpPtrAllocator ContentCacheAlloc;
- /// \brief Memoized information about all of the files tracked by this
+ /// Memoized information about all of the files tracked by this
/// SourceManager.
///
/// This map allows us to merge ContentCache entries based
@@ -572,29 +595,29 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// non-null, FileEntry pointers.
llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
- /// \brief True if the ContentCache for files that are overridden by other
+ /// True if the ContentCache for files that are overridden by other
/// files, should report the original file name. Defaults to true.
bool OverridenFilesKeepOriginalName = true;
- /// \brief True if non-system source files should be treated as volatile
+ /// True if non-system source files should be treated as volatile
/// (likely to change while trying to use them). Defaults to false.
bool UserFilesAreVolatile;
- /// \brief True if all files read during this compilation should be treated
+ /// True if all files read during this compilation should be treated
/// as transient (may not be present in later compilations using a module
/// file created from this compilation). Defaults to false.
bool FilesAreTransient = false;
struct OverriddenFilesInfoTy {
- /// \brief Files that have been overridden with the contents from another
+ /// Files that have been overridden with the contents from another
/// file.
llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
- /// \brief Files that were overridden with a memory buffer.
+ /// Files that were overridden with a memory buffer.
llvm::DenseSet<const FileEntry *> OverriddenFilesWithBuffer;
};
- /// \brief Lazily create the object keeping overridden files info, since
+ /// Lazily create the object keeping overridden files info, since
/// it is uncommonly used.
std::unique_ptr<OverriddenFilesInfoTy> OverriddenFilesInfo;
@@ -604,77 +627,77 @@ class SourceManager : public RefCountedBase<SourceManager> {
return *OverriddenFilesInfo;
}
- /// \brief Information about various memory buffers that we have read in.
+ /// Information about various memory buffers that we have read in.
///
/// All FileEntry* within the stored ContentCache objects are NULL,
/// as they do not refer to a file.
std::vector<SrcMgr::ContentCache*> MemBufferInfos;
- /// \brief The table of SLocEntries that are local to this module.
+ /// The table of SLocEntries that are local to this module.
///
/// Positive FileIDs are indexes into this table. Entry 0 indicates an invalid
/// expansion.
SmallVector<SrcMgr::SLocEntry, 0> LocalSLocEntryTable;
- /// \brief The table of SLocEntries that are loaded from other modules.
+ /// The table of SLocEntries that are loaded from other modules.
///
/// Negative FileIDs are indexes into this table. To get from ID to an index,
/// use (-ID - 2).
mutable SmallVector<SrcMgr::SLocEntry, 0> LoadedSLocEntryTable;
- /// \brief The starting offset of the next local SLocEntry.
+ /// The starting offset of the next local SLocEntry.
///
/// This is LocalSLocEntryTable.back().Offset + the size of that entry.
unsigned NextLocalOffset;
- /// \brief The starting offset of the latest batch of loaded SLocEntries.
+ /// The starting offset of the latest batch of loaded SLocEntries.
///
/// This is LoadedSLocEntryTable.back().Offset, except that that entry might
/// not have been loaded, so that value would be unknown.
unsigned CurrentLoadedOffset;
- /// \brief The highest possible offset is 2^31-1, so CurrentLoadedOffset
+ /// The highest possible offset is 2^31-1, so CurrentLoadedOffset
/// starts at 2^31.
static const unsigned MaxLoadedOffset = 1U << 31U;
- /// \brief A bitmap that indicates whether the entries of LoadedSLocEntryTable
+ /// A bitmap that indicates whether the entries of LoadedSLocEntryTable
/// have already been loaded from the external source.
///
/// Same indexing as LoadedSLocEntryTable.
llvm::BitVector SLocEntryLoaded;
- /// \brief An external source for source location entries.
+ /// An external source for source location entries.
ExternalSLocEntrySource *ExternalSLocEntries = nullptr;
- /// \brief A one-entry cache to speed up getFileID.
+ /// A one-entry cache to speed up getFileID.
///
/// LastFileIDLookup records the last FileID looked up or created, because it
/// is very common to look up many tokens from the same file.
mutable FileID LastFileIDLookup;
- /// \brief Holds information for \#line directives.
+ /// Holds information for \#line directives.
///
/// This is referenced by indices from SLocEntryTable.
LineTableInfo *LineTable = nullptr;
- /// \brief These ivars serve as a cache used in the getLineNumber
+ /// These ivars serve as a cache used in the getLineNumber
/// method which is used to speedup getLineNumber calls to nearby locations.
mutable FileID LastLineNoFileIDQuery;
mutable SrcMgr::ContentCache *LastLineNoContentCache;
mutable unsigned LastLineNoFilePos;
mutable unsigned LastLineNoResult;
- /// \brief The file ID for the main source file of the translation unit.
+ /// The file ID for the main source file of the translation unit.
FileID MainFileID;
- /// \brief The file ID for the precompiled preamble there is one.
+ /// The file ID for the precompiled preamble there is one.
FileID PreambleFileID;
// Statistics for -print-stats.
mutable unsigned NumLinearScans = 0;
mutable unsigned NumBinaryProbes = 0;
- /// \brief Associates a FileID with its "included/expanded in" decomposed
+ /// Associates a FileID with its "included/expanded in" decomposed
/// location.
///
/// Used to cache results from and speed-up \c getDecomposedIncludedLoc
@@ -702,14 +725,14 @@ class SourceManager : public RefCountedBase<SourceManager> {
mutable std::unique_ptr<SrcMgr::ContentCache> FakeContentCacheForRecovery;
- /// \brief Lazily computed map of macro argument chunks to their expanded
+ /// Lazily computed map of macro argument chunks to their expanded
/// source location.
using MacroArgsMap = std::map<unsigned, SourceLocation>;
mutable llvm::DenseMap<FileID, std::unique_ptr<MacroArgsMap>>
MacroArgsCacheMap;
- /// \brief The stack of modules being built, which is used to detect
+ /// The stack of modules being built, which is used to detect
/// cycles in the module dependency graph as modules are being built, as
/// well as to describe why we're rebuilding a particular module.
///
@@ -735,29 +758,29 @@ public:
FileManager &getFileManager() const { return FileMgr; }
- /// \brief Set true if the SourceManager should report the original file name
+ /// Set true if the SourceManager should report the original file name
/// for contents of files that were overridden by other files. Defaults to
/// true.
void setOverridenFilesKeepOriginalName(bool value) {
OverridenFilesKeepOriginalName = value;
}
- /// \brief True if non-system source files should be treated as volatile
+ /// True if non-system source files should be treated as volatile
/// (likely to change while trying to use them).
bool userFilesAreVolatile() const { return UserFilesAreVolatile; }
- /// \brief Retrieve the module build stack.
+ /// Retrieve the module build stack.
ModuleBuildStack getModuleBuildStack() const {
return StoredModuleBuildStack;
}
- /// \brief Set the module build stack.
+ /// Set the module build stack.
void setModuleBuildStack(ModuleBuildStack stack) {
StoredModuleBuildStack.clear();
StoredModuleBuildStack.append(stack.begin(), stack.end());
}
- /// \brief Push an entry to the module build stack.
+ /// Push an entry to the module build stack.
void pushModuleBuildStack(StringRef moduleName, FullSourceLoc importLoc) {
StoredModuleBuildStack.push_back(std::make_pair(moduleName.str(),importLoc));
}
@@ -766,28 +789,28 @@ public:
// MainFileID creation and querying methods.
//===--------------------------------------------------------------------===//
- /// \brief Returns the FileID of the main source file.
+ /// Returns the FileID of the main source file.
FileID getMainFileID() const { return MainFileID; }
- /// \brief Set the file ID for the main source file.
+ /// Set the file ID for the main source file.
void setMainFileID(FileID FID) {
MainFileID = FID;
}
- /// \brief Set the file ID for the precompiled preamble.
+ /// Set the file ID for the precompiled preamble.
void setPreambleFileID(FileID Preamble) {
assert(PreambleFileID.isInvalid() && "PreambleFileID already set!");
PreambleFileID = Preamble;
}
- /// \brief Get the file ID for the precompiled preamble if there is one.
+ /// Get the file ID for the precompiled preamble if there is one.
FileID getPreambleFileID() const { return PreambleFileID; }
//===--------------------------------------------------------------------===//
// Methods to create new FileID's and macro expansions.
//===--------------------------------------------------------------------===//
- /// \brief Create a new FileID that represents the specified file
+ /// Create a new FileID that represents the specified file
/// being \#included from the specified IncludePosition.
///
/// This translates NULL into standard input.
@@ -800,7 +823,7 @@ public:
return createFileID(IR, IncludePos, FileCharacter, LoadedID, LoadedOffset);
}
- /// \brief Create a new FileID that represents the specified memory buffer.
+ /// Create a new FileID that represents the specified memory buffer.
///
/// This does no caching of the buffer and takes ownership of the
/// MemoryBuffer, so only pass a MemoryBuffer to this once.
@@ -815,7 +838,7 @@ public:
enum UnownedTag { Unowned };
- /// \brief Create a new FileID that represents the specified memory buffer.
+ /// Create a new FileID that represents the specified memory buffer.
///
/// This does no caching of the buffer and takes ownership of the
/// MemoryBuffer, so only pass a MemoryBuffer to this once.
@@ -827,7 +850,7 @@ public:
IncludeLoc, FileCharacter, LoadedID, LoadedOffset);
}
- /// \brief Get the FileID for \p SourceFile if it exists. Otherwise, create a
+ /// Get the FileID for \p SourceFile if it exists. Otherwise, create a
/// new FileID for the \p SourceFile.
FileID getOrCreateFileID(const FileEntry *SourceFile,
SrcMgr::CharacteristicKind FileCharacter) {
@@ -836,7 +859,7 @@ public:
FileCharacter);
}
- /// \brief Return a new SourceLocation that encodes the
+ /// Return a new SourceLocation that encodes the
/// fact that a token from SpellingLoc should actually be referenced from
/// ExpansionLoc, and that it represents the expansion of a macro argument
/// into the function-like macro body.
@@ -844,24 +867,31 @@ public:
SourceLocation ExpansionLoc,
unsigned TokLength);
- /// \brief Return a new SourceLocation that encodes the fact
+ /// Return a new SourceLocation that encodes the fact
/// that a token from SpellingLoc should actually be referenced from
/// ExpansionLoc.
SourceLocation createExpansionLoc(SourceLocation Loc,
SourceLocation ExpansionLocStart,
SourceLocation ExpansionLocEnd,
unsigned TokLength,
+ bool ExpansionIsTokenRange = true,
int LoadedID = 0,
unsigned LoadedOffset = 0);
- /// \brief Retrieve the memory buffer associated with the given file.
+ /// Return a new SourceLocation that encodes that the token starting
+ /// at \p TokenStart ends prematurely at \p TokenEnd.
+ SourceLocation createTokenSplitLoc(SourceLocation SpellingLoc,
+ SourceLocation TokenStart,
+ SourceLocation TokenEnd);
+
+ /// Retrieve the memory buffer associated with the given file.
///
/// \param Invalid If non-NULL, will be set \c true if an error
/// occurs while retrieving the memory buffer.
llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
bool *Invalid = nullptr);
- /// \brief Override the contents of the given source file by providing an
+ /// Override the contents of the given source file by providing an
/// already-allocated buffer.
///
/// \param SourceFile the source file whose contents will be overridden.
@@ -878,7 +908,7 @@ public:
overrideFileContents(SourceFile, Buffer.release(), /*DoNotFree*/ false);
}
- /// \brief Override the given source file with another one.
+ /// Override the given source file with another one.
///
/// \param SourceFile the source file which will be overridden.
///
@@ -887,7 +917,7 @@ public:
void overrideFileContents(const FileEntry *SourceFile,
const FileEntry *NewFile);
- /// \brief Returns true if the file contents have been overridden.
+ /// Returns true if the file contents have been overridden.
bool isFileOverridden(const FileEntry *File) const {
if (OverriddenFilesInfo) {
if (OverriddenFilesInfo->OverriddenFilesWithBuffer.count(File))
@@ -899,16 +929,16 @@ public:
return false;
}
- /// \brief Disable overridding the contents of a file, previously enabled
+ /// Disable overridding the contents of a file, previously enabled
/// with #overrideFileContents.
///
/// This should be called before parsing has begun.
void disableFileContentsOverride(const FileEntry *File);
- /// \brief Specify that a file is transient.
+ /// Specify that a file is transient.
void setFileIsTransient(const FileEntry *SourceFile);
- /// \brief Specify that all files that are read during this compilation are
+ /// Specify that all files that are read during this compilation are
/// transient.
void setAllFilesAreTransient(bool Transient) {
FilesAreTransient = Transient;
@@ -918,7 +948,7 @@ public:
// FileID manipulation methods.
//===--------------------------------------------------------------------===//
- /// \brief Return the buffer for the specified FileID.
+ /// Return the buffer for the specified FileID.
///
/// If there is an error opening this buffer the first time, this
/// manufactures a temporary buffer and returns a non-empty error string.
@@ -952,7 +982,7 @@ public:
Invalid);
}
- /// \brief Returns the FileEntry record for the provided FileID.
+ /// Returns the FileEntry record for the provided FileID.
const FileEntry *getFileEntryForID(FileID FID) const {
bool MyInvalid = false;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
@@ -965,7 +995,7 @@ public:
return Content->OrigEntry;
}
- /// \brief Returns the FileEntry record for the provided SLocEntry.
+ /// Returns the FileEntry record for the provided SLocEntry.
const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const
{
const SrcMgr::ContentCache *Content = sloc.getFile().getContentCache();
@@ -974,14 +1004,14 @@ public:
return Content->OrigEntry;
}
- /// \brief Return a StringRef to the source buffer data for the
+ /// Return a StringRef to the source buffer data for the
/// specified FileID.
///
/// \param FID The file ID whose contents will be returned.
/// \param Invalid If non-NULL, will be set true if an error occurred.
StringRef getBufferData(FileID FID, bool *Invalid = nullptr) const;
- /// \brief Get the number of FileIDs (files and macros) that were created
+ /// Get the number of FileIDs (files and macros) that were created
/// during preprocessing of \p FID, including it.
unsigned getNumCreatedFIDsForFileID(FileID FID) const {
bool Invalid = false;
@@ -992,7 +1022,7 @@ public:
return Entry.getFile().NumCreatedFIDs;
}
- /// \brief Set the number of FileIDs (files and macros) that were created
+ /// Set the number of FileIDs (files and macros) that were created
/// during preprocessing of \p FID, including it.
void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs) const {
bool Invalid = false;
@@ -1008,7 +1038,7 @@ public:
// SourceLocation manipulation methods.
//===--------------------------------------------------------------------===//
- /// \brief Return the FileID for a SourceLocation.
+ /// Return the FileID for a SourceLocation.
///
/// This is a very hot method that is used for all SourceManager queries
/// that start with a SourceLocation object. It is responsible for finding
@@ -1024,14 +1054,14 @@ public:
return getFileIDSlow(SLocOffset);
}
- /// \brief Return the filename of the file containing a SourceLocation.
+ /// Return the filename of the file containing a SourceLocation.
StringRef getFilename(SourceLocation SpellingLoc) const {
if (const FileEntry *F = getFileEntryForID(getFileID(SpellingLoc)))
return F->getName();
return StringRef();
}
- /// \brief Return the source location corresponding to the first byte of
+ /// Return the source location corresponding to the first byte of
/// the specified file.
SourceLocation getLocForStartOfFile(FileID FID) const {
bool Invalid = false;
@@ -1043,7 +1073,7 @@ public:
return SourceLocation::getFileLoc(FileOffset);
}
- /// \brief Return the source location corresponding to the last byte of the
+ /// Return the source location corresponding to the last byte of the
/// specified file.
SourceLocation getLocForEndOfFile(FileID FID) const {
bool Invalid = false;
@@ -1055,7 +1085,7 @@ public:
return SourceLocation::getFileLoc(FileOffset + getFileIDSize(FID));
}
- /// \brief Returns the include location if \p FID is a \#include'd file
+ /// Returns the include location if \p FID is a \#include'd file
/// otherwise it returns an invalid location.
SourceLocation getIncludeLoc(FileID FID) const {
bool Invalid = false;
@@ -1066,7 +1096,7 @@ public:
return Entry.getFile().getIncludeLoc();
}
- // \brief Returns the import location if the given source location is
+ // Returns the import location if the given source location is
// located within a module, or an invalid location if the source location
// is within the current translation unit.
std::pair<SourceLocation, StringRef>
@@ -1081,7 +1111,7 @@ public:
return ExternalSLocEntries->getModuleImportLoc(FID.ID);
}
- /// \brief Given a SourceLocation object \p Loc, return the expansion
+ /// Given a SourceLocation object \p Loc, return the expansion
/// location referenced by the ID.
SourceLocation getExpansionLoc(SourceLocation Loc) const {
// Handle the non-mapped case inline, defer to out of line code to handle
@@ -1090,7 +1120,7 @@ public:
return getExpansionLocSlowCase(Loc);
}
- /// \brief Given \p Loc, if it is a macro location return the expansion
+ /// Given \p Loc, if it is a macro location return the expansion
/// location or the spelling location, depending on if it comes from a
/// macro argument or not.
SourceLocation getFileLoc(SourceLocation Loc) const {
@@ -1098,26 +1128,35 @@ public:
return getFileLocSlowCase(Loc);
}
- /// \brief Return the start/end of the expansion information for an
+ /// Return the start/end of the expansion information for an
/// expansion location.
///
/// \pre \p Loc is required to be an expansion location.
- std::pair<SourceLocation,SourceLocation>
- getImmediateExpansionRange(SourceLocation Loc) const;
+ CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const;
- /// \brief Given a SourceLocation object, return the range of
+ /// Given a SourceLocation object, return the range of
/// tokens covered by the expansion in the ultimate file.
- std::pair<SourceLocation,SourceLocation>
- getExpansionRange(SourceLocation Loc) const;
+ CharSourceRange getExpansionRange(SourceLocation Loc) const;
- /// \brief Given a SourceRange object, return the range of
- /// tokens covered by the expansion in the ultimate file.
- SourceRange getExpansionRange(SourceRange Range) const {
- return SourceRange(getExpansionRange(Range.getBegin()).first,
- getExpansionRange(Range.getEnd()).second);
+ /// Given a SourceRange object, return the range of
+ /// tokens or characters covered by the expansion in the ultimate file.
+ CharSourceRange getExpansionRange(SourceRange Range) const {
+ SourceLocation Begin = getExpansionRange(Range.getBegin()).getBegin();
+ CharSourceRange End = getExpansionRange(Range.getEnd());
+ return CharSourceRange(SourceRange(Begin, End.getEnd()),
+ End.isTokenRange());
+ }
+
+ /// Given a CharSourceRange object, return the range of
+ /// tokens or characters covered by the expansion in the ultimate file.
+ CharSourceRange getExpansionRange(CharSourceRange Range) const {
+ CharSourceRange Expansion = getExpansionRange(Range.getAsRange());
+ if (Expansion.getEnd() == Range.getEnd())
+ Expansion.setTokenRange(Range.isTokenRange());
+ return Expansion;
}
- /// \brief Given a SourceLocation object, return the spelling
+ /// Given a SourceLocation object, return the spelling
/// location referenced by the ID.
///
/// This is the place where the characters that make up the lexed token
@@ -1129,7 +1168,7 @@ public:
return getSpellingLocSlowCase(Loc);
}
- /// \brief Given a SourceLocation object, return the spelling location
+ /// Given a SourceLocation object, return the spelling location
/// referenced by the ID.
///
/// This is the first level down towards the place where the characters
@@ -1137,7 +1176,19 @@ public:
/// be used by clients.
SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const;
- /// \brief Decompose the specified location into a raw FileID + Offset pair.
+ /// Form a SourceLocation from a FileID and Offset pair.
+ SourceLocation getComposedLoc(FileID FID, unsigned Offset) const {
+ bool Invalid = false;
+ const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
+ if (Invalid)
+ return SourceLocation();
+
+ unsigned GlobalOffset = Entry.getOffset() + Offset;
+ return Entry.isFile() ? SourceLocation::getFileLoc(GlobalOffset)
+ : SourceLocation::getMacroLoc(GlobalOffset);
+ }
+
+ /// Decompose the specified location into a raw FileID + Offset pair.
///
/// The first element is the FileID, the second is the offset from the
/// start of the buffer of the location.
@@ -1150,7 +1201,7 @@ public:
return std::make_pair(FID, Loc.getOffset()-E.getOffset());
}
- /// \brief Decompose the specified location into a raw FileID + Offset pair.
+ /// Decompose the specified location into a raw FileID + Offset pair.
///
/// If the location is an expansion record, walk through it until we find
/// the final location expanded.
@@ -1169,7 +1220,7 @@ public:
return getDecomposedExpansionLocSlowCase(E);
}
- /// \brief Decompose the specified location into a raw FileID + Offset pair.
+ /// Decompose the specified location into a raw FileID + Offset pair.
///
/// If the location is an expansion record, walk through it until we find
/// its spelling record.
@@ -1187,11 +1238,11 @@ public:
return getDecomposedSpellingLocSlowCase(E, Offset);
}
- /// \brief Returns the "included/expanded in" decomposed location of the given
+ /// Returns the "included/expanded in" decomposed location of the given
/// FileID.
std::pair<FileID, unsigned> getDecomposedIncludedLoc(FileID FID) const;
- /// \brief Returns the offset from the start of the file that the
+ /// Returns the offset from the start of the file that the
/// specified SourceLocation represents.
///
/// This is not very meaningful for a macro ID.
@@ -1199,7 +1250,7 @@ public:
return getDecomposedLoc(SpellingLoc).second;
}
- /// \brief Tests whether the given source location represents a macro
+ /// Tests whether the given source location represents a macro
/// argument's expansion into the function-like macro definition.
///
/// \param StartLoc If non-null and function returns true, it is set to the
@@ -1211,14 +1262,14 @@ public:
bool isMacroArgExpansion(SourceLocation Loc,
SourceLocation *StartLoc = nullptr) const;
- /// \brief Tests whether the given source location represents the expansion of
+ /// Tests whether the given source location represents the expansion of
/// a macro body.
///
/// This is equivalent to testing whether the location is part of a macro
/// expansion but not the expansion of an argument to a function-like macro.
bool isMacroBodyExpansion(SourceLocation Loc) const;
- /// \brief Returns true if the given MacroID location points at the beginning
+ /// Returns true if the given MacroID location points at the beginning
/// of the immediate macro expansion.
///
/// \param MacroBegin If non-null and function returns true, it is set to the
@@ -1226,7 +1277,7 @@ public:
bool isAtStartOfImmediateMacroExpansion(SourceLocation Loc,
SourceLocation *MacroBegin = nullptr) const;
- /// \brief Returns true if the given MacroID location points at the character
+ /// Returns true if the given MacroID location points at the character
/// end of the immediate macro expansion.
///
/// \param MacroEnd If non-null and function returns true, it is set to the
@@ -1235,7 +1286,7 @@ public:
isAtEndOfImmediateMacroExpansion(SourceLocation Loc,
SourceLocation *MacroEnd = nullptr) const;
- /// \brief Returns true if \p Loc is inside the [\p Start, +\p Length)
+ /// Returns true if \p Loc is inside the [\p Start, +\p Length)
/// chunk of the source location address space.
///
/// If it's true and \p RelativeOffset is non-null, it will be set to the
@@ -1260,7 +1311,7 @@ public:
return false;
}
- /// \brief Return true if both \p LHS and \p RHS are in the local source
+ /// Return true if both \p LHS and \p RHS are in the local source
/// location address space or the loaded one.
///
/// If it's true and \p RelativeOffset is non-null, it will be set to the
@@ -1284,14 +1335,14 @@ public:
// Queries about the code at a SourceLocation.
//===--------------------------------------------------------------------===//
- /// \brief Return a pointer to the start of the specified location
+ /// Return a pointer to the start of the specified location
/// in the appropriate spelling MemoryBuffer.
///
/// \param Invalid If non-NULL, will be set \c true if an error occurs.
const char *getCharacterData(SourceLocation SL,
bool *Invalid = nullptr) const;
- /// \brief Return the column # for the specified file position.
+ /// Return the column # for the specified file position.
///
/// This is significantly cheaper to compute than the line number. This
/// returns zero if the column number isn't known. This may only be called
@@ -1306,7 +1357,7 @@ public:
unsigned getPresumedColumnNumber(SourceLocation Loc,
bool *Invalid = nullptr) const;
- /// \brief Given a SourceLocation, return the spelling line number
+ /// Given a SourceLocation, return the spelling line number
/// for the position indicated.
///
/// This requires building and caching a table of line offsets for the
@@ -1317,14 +1368,14 @@ public:
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
- /// \brief Return the filename or buffer identifier of the buffer the
+ /// Return the filename or buffer identifier of the buffer the
/// location is in.
///
/// Note that this name does not respect \#line directives. Use
/// getPresumedLoc for normal clients.
StringRef getBufferName(SourceLocation Loc, bool *Invalid = nullptr) const;
- /// \brief Return the file characteristic of the specified source
+ /// Return the file characteristic of the specified source
/// location, indicating whether this is a normal file, a system
/// header, or an "implicit extern C" system header.
///
@@ -1336,7 +1387,7 @@ public:
/// considered to be from a system header.
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const;
- /// \brief Returns the "presumed" location of a SourceLocation specifies.
+ /// Returns the "presumed" location of a SourceLocation specifies.
///
/// A "presumed location" can be modified by \#line or GNU line marker
/// directives. This provides a view on the data that a user should see
@@ -1352,7 +1403,7 @@ public:
PresumedLoc getPresumedLoc(SourceLocation Loc,
bool UseLineDirectives = true) const;
- /// \brief Returns whether the PresumedLoc for a given SourceLocation is
+ /// Returns whether the PresumedLoc for a given SourceLocation is
/// in the main file.
///
/// This computes the "presumed" location for a SourceLocation, then checks
@@ -1361,7 +1412,7 @@ public:
/// account.
bool isInMainFile(SourceLocation Loc) const;
- /// \brief Returns true if the spelling locations for both SourceLocations
+ /// Returns true if the spelling locations for both SourceLocations
/// are part of the same file buffer.
///
/// This check ignores line marker directives.
@@ -1369,7 +1420,7 @@ public:
return getFileID(Loc1) == getFileID(Loc2);
}
- /// \brief Returns true if the spelling location for the given location
+ /// Returns true if the spelling location for the given location
/// is in the main file buffer.
///
/// This check ignores line marker directives.
@@ -1377,25 +1428,25 @@ public:
return getFileID(Loc) == getMainFileID();
}
- /// \brief Returns if a SourceLocation is in a system header.
+ /// Returns if a SourceLocation is in a system header.
bool isInSystemHeader(SourceLocation Loc) const {
return isSystem(getFileCharacteristic(Loc));
}
- /// \brief Returns if a SourceLocation is in an "extern C" system header.
+ /// Returns if a SourceLocation is in an "extern C" system header.
bool isInExternCSystemHeader(SourceLocation Loc) const {
return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem;
}
- /// \brief Returns whether \p Loc is expanded from a macro in a system header.
+ /// Returns whether \p Loc is expanded from a macro in a system header.
bool isInSystemMacro(SourceLocation loc) const {
return loc.isMacroID() && isInSystemHeader(getSpellingLoc(loc));
}
- /// \brief The size of the SLocEntry that \p FID represents.
+ /// The size of the SLocEntry that \p FID represents.
unsigned getFileIDSize(FileID FID) const;
- /// \brief Given a specific FileID, returns true if \p Loc is inside that
+ /// Given a specific FileID, returns true if \p Loc is inside that
/// FileID chunk and sets relative offset (offset of \p Loc from beginning
/// of FileID) to \p relativeOffset.
bool isInFileID(SourceLocation Loc, FileID FID,
@@ -1414,10 +1465,10 @@ public:
// Line Table Manipulation Routines
//===--------------------------------------------------------------------===//
- /// \brief Return the uniqued ID for the specified filename.
+ /// Return the uniqued ID for the specified filename.
unsigned getLineTableFilenameID(StringRef Str);
- /// \brief Add a line note to the line table for the FileID and offset
+ /// Add a line note to the line table for the FileID and offset
/// specified by Loc.
///
/// If FilenameID is -1, it is considered to be unspecified.
@@ -1425,17 +1476,17 @@ public:
bool IsFileEntry, bool IsFileExit,
SrcMgr::CharacteristicKind FileKind);
- /// \brief Determine if the source manager has a line table.
+ /// Determine if the source manager has a line table.
bool hasLineTable() const { return LineTable != nullptr; }
- /// \brief Retrieve the stored line table.
+ /// Retrieve the stored line table.
LineTableInfo &getLineTable();
//===--------------------------------------------------------------------===//
// Queries for performance analysis.
//===--------------------------------------------------------------------===//
- /// \brief Return the total amount of physical memory allocated by the
+ /// Return the total amount of physical memory allocated by the
/// ContentCache allocator.
size_t getContentCacheSize() const {
return ContentCacheAlloc.getTotalMemory();
@@ -1449,11 +1500,11 @@ public:
: malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
};
- /// \brief Return the amount of memory used by memory buffers, breaking down
+ /// Return the amount of memory used by memory buffers, breaking down
/// by heap-backed versus mmap'ed memory.
MemoryBufferSizes getMemoryBufferSizes() const;
- /// \brief Return the amount of memory used for various side tables and
+ /// Return the amount of memory used for various side tables and
/// data structures in the SourceManager.
size_t getDataStructureSizes() const;
@@ -1461,25 +1512,25 @@ public:
// Other miscellaneous methods.
//===--------------------------------------------------------------------===//
- /// \brief Get the source location for the given file:line:col triplet.
+ /// Get the source location for the given file:line:col triplet.
///
/// If the source file is included multiple times, the source location will
/// be based upon the first inclusion.
SourceLocation translateFileLineCol(const FileEntry *SourceFile,
unsigned Line, unsigned Col) const;
- /// \brief Get the FileID for the given file.
+ /// Get the FileID for the given file.
///
/// If the source file is included multiple times, the FileID will be the
/// first inclusion.
FileID translateFile(const FileEntry *SourceFile) const;
- /// \brief Get the source location in \p FID for the given line:col.
+ /// Get the source location in \p FID for the given line:col.
/// Returns null location if \p FID is not a file SLocEntry.
SourceLocation translateLineCol(FileID FID,
unsigned Line, unsigned Col) const;
- /// \brief If \p Loc points inside a function macro argument, the returned
+ /// If \p Loc points inside a function macro argument, the returned
/// location will be the macro location in which the argument was expanded.
/// If a macro argument is used multiple times, the expanded location will
/// be at the first expansion of the argument.
@@ -1490,12 +1541,12 @@ public:
/// where 'foo' was expanded into.
SourceLocation getMacroArgExpandedLocation(SourceLocation Loc) const;
- /// \brief Determines the order of 2 source locations in the translation unit.
+ /// Determines the order of 2 source locations in the translation unit.
///
/// \returns true if LHS source location comes before RHS, false otherwise.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const;
- /// \brief Determines whether the two decomposed source location is in the
+ /// Determines whether the two decomposed source location is in the
/// same translation unit. As a byproduct, it also calculates the order
/// of the source locations in case they are in the same TU.
///
@@ -1506,13 +1557,13 @@ public:
isInTheSameTranslationUnit(std::pair<FileID, unsigned> &LOffs,
std::pair<FileID, unsigned> &ROffs) const;
- /// \brief Determines the order of 2 source locations in the "source location
+ /// Determines the order of 2 source locations in the "source location
/// address space".
bool isBeforeInSLocAddrSpace(SourceLocation LHS, SourceLocation RHS) const {
return isBeforeInSLocAddrSpace(LHS, RHS.getOffset());
}
- /// \brief Determines the order of a source location and a source location
+ /// Determines the order of a source location and a source location
/// offset in the "source location address space".
///
/// Note that we always consider source locations loaded from
@@ -1544,25 +1595,25 @@ public:
return FileInfos.find(File) != FileInfos.end();
}
- /// \brief Print statistics to stderr.
+ /// Print statistics to stderr.
void PrintStats() const;
void dump() const;
- /// \brief Get the number of local SLocEntries we have.
+ /// Get the number of local SLocEntries we have.
unsigned local_sloc_entry_size() const { return LocalSLocEntryTable.size(); }
- /// \brief Get a local SLocEntry. This is exposed for indexing.
+ /// Get a local SLocEntry. This is exposed for indexing.
const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index,
bool *Invalid = nullptr) const {
assert(Index < LocalSLocEntryTable.size() && "Invalid index");
return LocalSLocEntryTable[Index];
}
- /// \brief Get the number of loaded SLocEntries we have.
+ /// Get the number of loaded SLocEntries we have.
unsigned loaded_sloc_entry_size() const { return LoadedSLocEntryTable.size();}
- /// \brief Get a loaded SLocEntry. This is exposed for indexing.
+ /// Get a loaded SLocEntry. This is exposed for indexing.
const SrcMgr::SLocEntry &getLoadedSLocEntry(unsigned Index,
bool *Invalid = nullptr) const {
assert(Index < LoadedSLocEntryTable.size() && "Invalid index");
@@ -1588,7 +1639,7 @@ public:
ExternalSLocEntries = Source;
}
- /// \brief Allocate a number of loaded SLocEntries, which will be actually
+ /// Allocate a number of loaded SLocEntries, which will be actually
/// loaded on demand from the external source.
///
/// NumSLocEntries will be allocated, which occupy a total of TotalSize space
@@ -1597,23 +1648,23 @@ public:
std::pair<int, unsigned>
AllocateLoadedSLocEntries(unsigned NumSLocEntries, unsigned TotalSize);
- /// \brief Returns true if \p Loc came from a PCH/Module.
+ /// Returns true if \p Loc came from a PCH/Module.
bool isLoadedSourceLocation(SourceLocation Loc) const {
return Loc.getOffset() >= CurrentLoadedOffset;
}
- /// \brief Returns true if \p Loc did not come from a PCH/Module.
+ /// Returns true if \p Loc did not come from a PCH/Module.
bool isLocalSourceLocation(SourceLocation Loc) const {
return Loc.getOffset() < NextLocalOffset;
}
- /// \brief Returns true if \p FID came from a PCH/Module.
+ /// Returns true if \p FID came from a PCH/Module.
bool isLoadedFileID(FileID FID) const {
assert(FID.ID != -1 && "Using FileID sentinel value");
return FID.ID < 0;
}
- /// \brief Returns true if \p FID did not come from a PCH/Module.
+ /// Returns true if \p FID did not come from a PCH/Module.
bool isLocalFileID(FileID FID) const {
return !isLoadedFileID(FID);
}
@@ -1631,9 +1682,12 @@ public:
// Otherwise, the caller of the macro is located where this macro is
// expanded (while the spelling is part of the macro definition).
- return getImmediateExpansionRange(Loc).first;
+ return getImmediateExpansionRange(Loc).getBegin();
}
+ /// \return Location of the top-level macro caller.
+ SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const;
+
private:
friend class ASTReader;
friend class ASTWriter;
@@ -1643,7 +1697,7 @@ private:
const SrcMgr::SLocEntry &loadSLocEntry(unsigned Index, bool *Invalid) const;
- /// \brief Get the entry with the given unwrapped FileID.
+ /// Get the entry with the given unwrapped FileID.
const SrcMgr::SLocEntry &getSLocEntryByID(int ID,
bool *Invalid = nullptr) const {
assert(ID != -1 && "Using FileID sentinel value");
@@ -1664,7 +1718,7 @@ private:
int LoadedID = 0,
unsigned LoadedOffset = 0);
- /// \brief Return true if the specified FileID contains the
+ /// Return true if the specified FileID contains the
/// specified SourceLocation offset. This is a very hot method.
inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const {
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
@@ -1684,15 +1738,15 @@ private:
return SLocOffset < getSLocEntryByID(FID.ID+1).getOffset();
}
- /// \brief Returns the previous in-order FileID or an invalid FileID if there
+ /// Returns the previous in-order FileID or an invalid FileID if there
/// is no previous one.
FileID getPreviousFileID(FileID FID) const;
- /// \brief Returns the next in-order FileID or an invalid FileID if there is
+ /// Returns the next in-order FileID or an invalid FileID if there is
/// no next one.
FileID getNextFileID(FileID FID) const;
- /// \brief Create a new fileID for the specified ContentCache and
+ /// Create a new fileID for the specified ContentCache and
/// include position.
///
/// This works regardless of whether the ContentCache corresponds to a
@@ -1706,7 +1760,7 @@ private:
getOrCreateContentCache(const FileEntry *SourceFile,
bool isSystemFile = false);
- /// \brief Create a new ContentCache for the specified memory buffer.
+ /// Create a new ContentCache for the specified memory buffer.
const SrcMgr::ContentCache *
createMemBufferContentCache(llvm::MemoryBuffer *Buf, bool DoNotFree);
@@ -1731,11 +1785,11 @@ private:
unsigned ExpansionLength) const;
};
-/// \brief Comparison function object.
+/// Comparison function object.
template<typename T>
class BeforeThanCompare;
-/// \brief Compare two source locations.
+/// Compare two source locations.
template<>
class BeforeThanCompare<SourceLocation> {
SourceManager &SM;
@@ -1748,7 +1802,7 @@ public:
}
};
-/// \brief Compare two non-overlapping source ranges.
+/// Compare two non-overlapping source ranges.
template<>
class BeforeThanCompare<SourceRange> {
SourceManager &SM;
@@ -1761,6 +1815,28 @@ public:
}
};
+/// SourceManager and necessary depdencies (e.g. VFS, FileManager) for a single
+/// in-memorty file.
+class SourceManagerForFile {
+public:
+ /// Creates SourceManager and necessary depdencies (e.g. VFS, FileManager).
+ /// The main file in the SourceManager will be \p FileName with \p Content.
+ SourceManagerForFile(StringRef FileName, StringRef Content);
+
+ SourceManager &get() {
+ assert(SourceMgr);
+ return *SourceMgr;
+ }
+
+private:
+ // The order of these fields are important - they should be in the same order
+ // as they are created in `createSourceManagerForFile` so that they can be
+ // deleted in the reverse order as they are created.
+ std::unique_ptr<FileManager> FileMgr;
+ std::unique_ptr<DiagnosticsEngine> Diagnostics;
+ std::unique_ptr<SourceManager> SourceMgr;
+};
+
} // namespace clang
#endif // LLVM_CLANG_BASIC_SOURCEMANAGER_H
diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h
index edd910e704128..68873be594d4b 100644
--- a/include/clang/Basic/SourceManagerInternals.h
+++ b/include/clang/Basic/SourceManagerInternals.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Defines implementation details of the clang::SourceManager class.
+/// Defines implementation details of the clang::SourceManager class.
//
//===----------------------------------------------------------------------===//
@@ -31,20 +31,20 @@ namespace clang {
//===----------------------------------------------------------------------===//
struct LineEntry {
- /// \brief The offset in this file that the line entry occurs at.
+ /// The offset in this file that the line entry occurs at.
unsigned FileOffset;
- /// \brief The presumed line number of this line entry: \#line 4.
+ /// The presumed line number of this line entry: \#line 4.
unsigned LineNo;
- /// \brief The ID of the filename identified by this line entry:
+ /// The ID of the filename identified by this line entry:
/// \#line 4 "foo.c". This is -1 if not specified.
int FilenameID;
- /// \brief Set the 0 if no flags, 1 if a system header,
+ /// Set the 0 if no flags, 1 if a system header,
SrcMgr::CharacteristicKind FileKind;
- /// \brief The offset of the virtual include stack location,
+ /// The offset of the virtual include stack location,
/// which is manipulated by GNU linemarker directives.
///
/// If this is 0 then there is no virtual \#includer.
@@ -77,9 +77,9 @@ inline bool operator<(unsigned Offset, const LineEntry &E) {
return Offset < E.FileOffset;
}
-/// \brief Used to hold and unique data used to represent \#line information.
+/// Used to hold and unique data used to represent \#line information.
class LineTableInfo {
- /// \brief Map used to assign unique IDs to filenames in \#line directives.
+ /// Map used to assign unique IDs to filenames in \#line directives.
///
/// This allows us to unique the filenames that
/// frequently reoccur and reference them with indices. FilenameIDs holds
@@ -88,7 +88,7 @@ class LineTableInfo {
llvm::StringMap<unsigned, llvm::BumpPtrAllocator> FilenameIDs;
std::vector<llvm::StringMapEntry<unsigned>*> FilenamesByID;
- /// \brief Map from FileIDs to a list of line entries (sorted by the offset
+ /// Map from FileIDs to a list of line entries (sorted by the offset
/// at which they occur in the file).
std::map<FileID, std::vector<LineEntry>> LineEntries;
@@ -113,7 +113,7 @@ public:
unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
- /// \brief Find the line entry nearest to FID that is before it.
+ /// Find the line entry nearest to FID that is before it.
///
/// If there is no line entry before \p Offset in \p FID, returns null.
const LineEntry *FindNearestLineEntry(FileID FID, unsigned Offset);
@@ -124,7 +124,7 @@ public:
iterator begin() { return LineEntries.begin(); }
iterator end() { return LineEntries.end(); }
- /// \brief Add a new line entry that has already been encoded into
+ /// Add a new line entry that has already been encoded into
/// the internal representation of the line table.
void AddEntry(FileID FID, const std::vector<LineEntry> &Entries);
};
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index 377534baab06b..303b77e448053 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines various enumerations that describe declaration and
+/// Defines various enumerations that describe declaration and
/// type specifiers.
///
//===----------------------------------------------------------------------===//
@@ -21,7 +21,7 @@
#include "llvm/Support/ErrorHandling.h"
namespace clang {
- /// \brief Specifies the width of a type, e.g., short, long, or long long.
+ /// Specifies the width of a type, e.g., short, long, or long long.
enum TypeSpecifierWidth {
TSW_unspecified,
TSW_short,
@@ -29,7 +29,7 @@ namespace clang {
TSW_longlong
};
- /// \brief Specifies the signedness of a type, e.g., signed or unsigned.
+ /// Specifies the signedness of a type, e.g., signed or unsigned.
enum TypeSpecifierSign {
TSS_unspecified,
TSS_signed,
@@ -41,18 +41,21 @@ namespace clang {
TSP_pipe
};
- /// \brief Specifies the kind of type.
+ /// Specifies the kind of type.
enum TypeSpecifierType {
TST_unspecified,
TST_void,
TST_char,
TST_wchar, // C++ wchar_t
+ TST_char8, // C++20 char8_t (proposed)
TST_char16, // C++11 char16_t
TST_char32, // C++11 char32_t
TST_int,
TST_int128,
TST_half, // OpenCL half, ARM NEON __fp16
TST_Float16, // C11 extension ISO/IEC TS 18661-3
+ TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension
+ TST_Fract,
TST_float,
TST_double,
TST_float128,
@@ -80,7 +83,7 @@ namespace clang {
TST_error // erroneous type
};
- /// \brief Structure that packs information about the type specifiers that
+ /// Structure that packs information about the type specifiers that
/// were written in a particular type specifier sequence.
struct WrittenBuiltinSpecs {
static_assert(TST_error < 1 << 6, "Type bitfield not wide enough for TST");
@@ -90,7 +93,7 @@ namespace clang {
unsigned ModeAttr : 1;
};
- /// \brief A C++ access specifier (public, private, protected), plus the
+ /// A C++ access specifier (public, private, protected), plus the
/// special value "none" which means different things in different contexts.
enum AccessSpecifier {
AS_public,
@@ -99,24 +102,24 @@ namespace clang {
AS_none
};
- /// \brief The categorization of expression values, currently following the
+ /// The categorization of expression values, currently following the
/// C++11 scheme.
enum ExprValueKind {
- /// \brief An r-value expression (a pr-value in the C++11 taxonomy)
+ /// An r-value expression (a pr-value in the C++11 taxonomy)
/// produces a temporary value.
VK_RValue,
- /// \brief An l-value expression is a reference to an object with
+ /// An l-value expression is a reference to an object with
/// independent storage.
VK_LValue,
- /// \brief An x-value expression is a reference to an object with
+ /// An x-value expression is a reference to an object with
/// independent storage but which can be "moved", i.e.
/// efficiently cannibalized for its resources.
VK_XValue
};
- /// \brief A further classification of the kind of object referenced by an
+ /// A further classification of the kind of object referenced by an
/// l-value or x-value.
enum ExprObjectKind {
/// An ordinary object is located at an address in memory.
@@ -138,7 +141,7 @@ namespace clang {
OK_ObjCSubscript
};
- /// \brief Describes the kind of template specialization that a
+ /// Describes the kind of template specialization that a
/// particular template specialization declaration represents.
enum TemplateSpecializationKind {
/// This template specialization was formed from a template-id but
@@ -161,14 +164,14 @@ namespace clang {
TSK_ExplicitInstantiationDefinition
};
- /// \brief Determine whether this template specialization kind refers
+ /// Determine whether this template specialization kind refers
/// to an instantiation of an entity (as opposed to a non-template or
/// an explicit specialization).
inline bool isTemplateInstantiation(TemplateSpecializationKind Kind) {
return Kind != TSK_Undeclared && Kind != TSK_ExplicitSpecialization;
}
- /// \brief True if this template specialization kind is an explicit
+ /// True if this template specialization kind is an explicit
/// specialization, explicit instantiation declaration, or explicit
/// instantiation definition.
inline bool isTemplateExplicitInstantiationOrSpecialization(
@@ -186,7 +189,7 @@ namespace clang {
llvm_unreachable("bad template specialization kind");
}
- /// \brief Thread storage-class-specifier.
+ /// Thread storage-class-specifier.
enum ThreadStorageClassSpecifier {
TSCS_unspecified,
/// GNU __thread.
@@ -199,7 +202,7 @@ namespace clang {
TSCS__Thread_local
};
- /// \brief Storage classes.
+ /// Storage classes.
enum StorageClass {
// These are legal on both functions and variables.
SC_None,
@@ -212,24 +215,24 @@ namespace clang {
SC_Register
};
- /// \brief Checks whether the given storage class is legal for functions.
+ /// Checks whether the given storage class is legal for functions.
inline bool isLegalForFunction(StorageClass SC) {
return SC <= SC_PrivateExtern;
}
- /// \brief Checks whether the given storage class is legal for variables.
+ /// Checks whether the given storage class is legal for variables.
inline bool isLegalForVariable(StorageClass SC) {
return true;
}
- /// \brief In-class initialization styles for non-static data members.
+ /// In-class initialization styles for non-static data members.
enum InClassInitStyle {
ICIS_NoInit, ///< No in-class initializer.
ICIS_CopyInit, ///< Copy initialization.
ICIS_ListInit ///< Direct list-initialization.
};
- /// \brief CallingConv - Specifies the calling convention that a function uses.
+ /// CallingConv - Specifies the calling convention that a function uses.
enum CallingConv {
CC_C, // __attribute__((cdecl))
CC_X86StdCall, // __attribute__((stdcall))
@@ -250,7 +253,7 @@ namespace clang {
CC_PreserveAll, // __attribute__((preserve_all))
};
- /// \brief Checks whether the given calling convention supports variadic
+ /// Checks whether the given calling convention supports variadic
/// calls. Unprototyped calls also use the variadic call rules.
inline bool supportsVariadicCall(CallingConv CC) {
switch (CC) {
@@ -269,7 +272,7 @@ namespace clang {
}
}
- /// \brief The storage duration for an object (per C++ [basic.stc]).
+ /// The storage duration for an object (per C++ [basic.stc]).
enum StorageDuration {
SD_FullExpression, ///< Full-expression storage duration (for temporaries).
SD_Automatic, ///< Automatic storage duration (most local variables).
@@ -291,11 +294,17 @@ namespace clang {
Unspecified
};
+ /// Return true if \p L has a weaker nullability annotation than \p R. The
+ /// ordering is: Unspecified < Nullable < NonNull.
+ inline bool hasWeakerNullability(NullabilityKind L, NullabilityKind R) {
+ return uint8_t(L) > uint8_t(R);
+ }
+
/// Retrieve the spelling of the given nullability kind.
llvm::StringRef getNullabilitySpelling(NullabilityKind kind,
bool isContextSensitive = false);
- /// \brief Kinds of parameter ABI.
+ /// Kinds of parameter ABI.
enum class ParameterABI {
/// This parameter uses ordinary ABI rules for its type.
Ordinary,
diff --git a/include/clang/Basic/Stack.h b/include/clang/Basic/Stack.h
new file mode 100644
index 0000000000000..15a37c6d5949f
--- /dev/null
+++ b/include/clang/Basic/Stack.h
@@ -0,0 +1,27 @@
+//===--- Stack.h - Utilities for dealing with stack space -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Defines utilities for dealing with stack allocation and stack space.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_STACK_H
+#define LLVM_CLANG_BASIC_STACK_H
+
+#include <cstddef>
+
+namespace clang {
+ /// The amount of stack space that Clang would like to be provided with.
+ /// If less than this much is available, we may be unable to reach our
+ /// template instantiation depth limit and other similar limits.
+ constexpr size_t DesiredStackSize = 8 << 20;
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_STACK_H
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index 0d21845fbf8b1..506da07203385 100644
--- a/include/clang/Basic/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -57,6 +57,7 @@ def Expr : Stmt<1>;
def PredefinedExpr : DStmt<Expr>;
def DeclRefExpr : DStmt<Expr>;
def IntegerLiteral : DStmt<Expr>;
+def FixedPointLiteral : DStmt<Expr>;
def FloatingLiteral : DStmt<Expr>;
def ImaginaryLiteral : DStmt<Expr>;
def StringLiteral : DStmt<Expr>;
diff --git a/include/clang/Basic/SyncScope.h b/include/clang/Basic/SyncScope.h
index 09ac0052185af..db4461eda0134 100644
--- a/include/clang/Basic/SyncScope.h
+++ b/include/clang/Basic/SyncScope.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Provides definitions for the atomic synchronization scopes.
+/// Provides definitions for the atomic synchronization scopes.
///
//===----------------------------------------------------------------------===//
@@ -22,7 +22,7 @@
namespace clang {
-/// \brief Defines synch scope values used internally by clang.
+/// Defines synch scope values used internally by clang.
///
/// The enum values start from 0 and are contiguous. They are mainly used for
/// enumerating all supported synch scope values and mapping them to LLVM
@@ -62,36 +62,36 @@ inline llvm::StringRef getAsString(SyncScope S) {
llvm_unreachable("Invalid synch scope");
}
-/// \brief Defines the kind of atomic scope models.
+/// Defines the kind of atomic scope models.
enum class AtomicScopeModelKind { None, OpenCL };
-/// \brief Defines the interface for synch scope model.
+/// Defines the interface for synch scope model.
class AtomicScopeModel {
public:
virtual ~AtomicScopeModel() {}
- /// \brief Maps language specific synch scope values to internal
+ /// Maps language specific synch scope values to internal
/// SyncScope enum.
virtual SyncScope map(unsigned S) const = 0;
- /// \brief Check if the compile-time constant synch scope value
+ /// Check if the compile-time constant synch scope value
/// is valid.
virtual bool isValid(unsigned S) const = 0;
- /// \brief Get all possible synch scope values that might be
+ /// Get all possible synch scope values that might be
/// encountered at runtime for the current language.
virtual ArrayRef<unsigned> getRuntimeValues() const = 0;
- /// \brief If atomic builtin function is called with invalid
+ /// If atomic builtin function is called with invalid
/// synch scope value at runtime, it will fall back to a valid
/// synch scope value returned by this function.
virtual unsigned getFallBackValue() const = 0;
- /// \brief Create an atomic scope model by AtomicScopeModelKind.
+ /// Create an atomic scope model by AtomicScopeModelKind.
/// \return an empty std::unique_ptr for AtomicScopeModelKind::None.
static std::unique_ptr<AtomicScopeModel> create(AtomicScopeModelKind K);
};
-/// \brief Defines the synch scope model for OpenCL.
+/// Defines the synch scope model for OpenCL.
class AtomicScopeOpenCLModel : public AtomicScopeModel {
public:
/// The enum values match the pre-defined macros
diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h
index 8f4f5e9a74dd8..75a3811007cc5 100644
--- a/include/clang/Basic/TargetBuiltins.h
+++ b/include/clang/Basic/TargetBuiltins.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Enumerates target-specific builtins in their own namespaces within
+/// Enumerates target-specific builtins in their own namespaces within
/// namespace ::clang.
///
//===----------------------------------------------------------------------===//
@@ -31,7 +31,7 @@ namespace clang {
};
}
- /// \brief ARM builtins
+ /// ARM builtins
namespace ARM {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
@@ -42,7 +42,7 @@ namespace clang {
};
}
- /// \brief AArch64 builtins
+ /// AArch64 builtins
namespace AArch64 {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
@@ -53,7 +53,7 @@ namespace clang {
};
}
- /// \brief PPC builtins
+ /// PPC builtins
namespace PPC {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
@@ -63,7 +63,7 @@ namespace clang {
};
}
- /// \brief NVPTX builtins
+ /// NVPTX builtins
namespace NVPTX {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
@@ -73,7 +73,7 @@ namespace clang {
};
}
- /// \brief AMDGPU builtins
+ /// AMDGPU builtins
namespace AMDGPU {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
@@ -83,7 +83,7 @@ namespace clang {
};
}
- /// \brief X86 builtins
+ /// X86 builtins
namespace X86 {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
@@ -97,7 +97,7 @@ namespace clang {
};
}
- /// \brief Flags to identify the types for overloaded Neon builtins.
+ /// Flags to identify the types for overloaded Neon builtins.
///
/// These must be kept in sync with the flags in utils/TableGen/NeonEmitter.h.
class NeonTypeFlags {
@@ -140,7 +140,7 @@ namespace clang {
bool isQuad() const { return (Flags & QuadFlag) != 0; }
};
- /// \brief Hexagon builtins
+ /// Hexagon builtins
namespace Hexagon {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
@@ -150,7 +150,7 @@ namespace clang {
};
}
- /// \brief Nios2 builtins
+ /// Nios2 builtins
namespace Nios2 {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
@@ -160,7 +160,7 @@ namespace clang {
};
}
- /// \brief MIPS builtins
+ /// MIPS builtins
namespace Mips {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
@@ -170,7 +170,7 @@ namespace clang {
};
}
- /// \brief XCore builtins
+ /// XCore builtins
namespace XCore {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
@@ -180,7 +180,7 @@ namespace clang {
};
}
- /// \brief Le64 builtins
+ /// Le64 builtins
namespace Le64 {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
@@ -190,7 +190,7 @@ namespace clang {
};
}
- /// \brief SystemZ builtins
+ /// SystemZ builtins
namespace SystemZ {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
@@ -200,7 +200,7 @@ namespace clang {
};
}
- /// \brief WebAssembly builtins
+ /// WebAssembly builtins
namespace WebAssembly {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h
index 7fb1f826b0f64..455121a98f338 100644
--- a/include/clang/Basic/TargetCXXABI.h
+++ b/include/clang/Basic/TargetCXXABI.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the TargetCXXABI class, which abstracts details of the
+/// Defines the TargetCXXABI class, which abstracts details of the
/// C++ ABI that we're targeting.
///
//===----------------------------------------------------------------------===//
@@ -20,10 +20,10 @@
namespace clang {
-/// \brief The basic abstraction for the target C++ ABI.
+/// The basic abstraction for the target C++ ABI.
class TargetCXXABI {
public:
- /// \brief The basic C++ ABI kind.
+ /// The basic C++ ABI kind.
enum Kind {
/// The generic Itanium ABI is the standard ABI of most open-source
/// and Unix-like platforms. It is the primary ABI targeted by
@@ -131,7 +131,7 @@ public:
Kind getKind() const { return TheKind; }
- /// \brief Does this ABI generally fall into the Itanium family of ABIs?
+ /// Does this ABI generally fall into the Itanium family of ABIs?
bool isItaniumFamily() const {
switch (getKind()) {
case GenericAArch64:
@@ -150,7 +150,7 @@ public:
llvm_unreachable("bad ABI kind");
}
- /// \brief Is this ABI an MSVC-compatible ABI?
+ /// Is this ABI an MSVC-compatible ABI?
bool isMicrosoft() const {
switch (getKind()) {
case GenericAArch64:
@@ -169,7 +169,7 @@ public:
llvm_unreachable("bad ABI kind");
}
- /// \brief Are member functions differently aligned?
+ /// Are member functions differently aligned?
///
/// Many Itanium-style C++ ABIs require member functions to be aligned, so
/// that a pointer to such a function is guaranteed to have a zero in the
@@ -199,13 +199,6 @@ public:
llvm_unreachable("bad ABI kind");
}
- /// \brief Is the default C++ member function calling convention
- /// the same as the default calling convention?
- bool isMemberFunctionCCDefault() const {
- // Right now, this is always false for Microsoft.
- return !isMicrosoft();
- }
-
/// Are arguments to a call destroyed left to right in the callee?
/// This is a fundamental language change, since it implies that objects
/// passed by value do *not* live to the end of the full expression.
@@ -217,25 +210,25 @@ public:
return isMicrosoft();
}
- /// \brief Does this ABI have different entrypoints for complete-object
+ /// Does this ABI have different entrypoints for complete-object
/// and base-subobject constructors?
bool hasConstructorVariants() const {
return isItaniumFamily();
}
- /// \brief Does this ABI allow virtual bases to be primary base classes?
+ /// Does this ABI allow virtual bases to be primary base classes?
bool hasPrimaryVBases() const {
return isItaniumFamily();
}
- /// \brief Does this ABI use key functions? If so, class data such as the
+ /// Does this ABI use key functions? If so, class data such as the
/// vtable is emitted with strong linkage by the TU containing the key
/// function.
bool hasKeyFunctions() const {
return isItaniumFamily();
}
- /// \brief Can an out-of-line inline function serve as a key function?
+ /// Can an out-of-line inline function serve as a key function?
///
/// This flag is only useful in ABIs where type data (for example,
/// vtables and type_info objects) are emitted only after processing
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 6ba58779114f5..ec5c59b239069 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the clang::TargetInfo interface.
+/// Defines the clang::TargetInfo interface.
///
//===----------------------------------------------------------------------===//
@@ -20,7 +20,6 @@
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetCXXABI.h"
#include "clang/Basic/TargetOptions.h"
-#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/Optional.h"
@@ -30,6 +29,7 @@
#include "llvm/ADT/Triple.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/VersionTuple.h"
#include <cassert>
#include <string>
#include <vector>
@@ -49,7 +49,7 @@ class SourceManager;
namespace Builtin { struct Info; }
-/// \brief Exposes information about the current target.
+/// Exposes information about the current target.
///
class TargetInfo : public RefCountedBase<TargetInfo> {
std::shared_ptr<TargetOptions> TargetOpts;
@@ -61,6 +61,8 @@ protected:
bool TLSSupported;
bool VLASupported;
bool NoAsmVariants; // True if {|} are normal characters.
+ bool HasLegalHalfType; // True if the backend supports operations on the half
+ // LLVM IR type.
bool HasFloat128;
unsigned char PointerWidth, PointerAlign;
unsigned char BoolWidth, BoolAlign;
@@ -72,6 +74,33 @@ protected:
unsigned char LargeArrayMinWidth, LargeArrayAlign;
unsigned char LongWidth, LongAlign;
unsigned char LongLongWidth, LongLongAlign;
+
+ // Fixed point bit widths
+ unsigned char ShortAccumWidth, ShortAccumAlign;
+ unsigned char AccumWidth, AccumAlign;
+ unsigned char LongAccumWidth, LongAccumAlign;
+ unsigned char ShortFractWidth, ShortFractAlign;
+ unsigned char FractWidth, FractAlign;
+ unsigned char LongFractWidth, LongFractAlign;
+
+ // If true, unsigned fixed point types have the same number of fractional bits
+ // as their signed counterparts, forcing the unsigned types to have one extra
+ // bit of padding. Otherwise, unsigned fixed point types have
+ // one more fractional bit than its corresponding signed type. This is false
+ // by default.
+ bool PaddingOnUnsignedFixedPoint;
+
+ // Fixed point integral and fractional bit sizes
+ // Saturated types share the same integral/fractional bits as their
+ // corresponding unsaturated types.
+ // For simplicity, the fractional bits in a _Fract type will be one less the
+ // width of that _Fract type. This leaves all signed _Fract types having no
+ // padding and unsigned _Fract types will only have 1 bit of padding after the
+ // sign if PaddingOnUnsignedFixedPoint is set.
+ unsigned char ShortAccumScale;
+ unsigned char AccumScale;
+ unsigned char LongAccumScale;
+
unsigned char SuitableAlign;
unsigned char DefaultAlignForAttributeAligned;
unsigned char MinGlobalAlign;
@@ -107,7 +136,7 @@ protected:
}
public:
- /// \brief Construct a target for the given options.
+ /// Construct a target for the given options.
///
/// \param Opts - The options to use to initialize the target. The target may
/// modify the options to canonicalize the target feature information to match
@@ -118,7 +147,7 @@ public:
virtual ~TargetInfo();
- /// \brief Retrieve the target options.
+ /// Retrieve the target options.
TargetOptions &getTargetOpts() const {
assert(TargetOpts && "Missing target options");
return *TargetOpts;
@@ -147,7 +176,7 @@ public:
Float128
};
- /// \brief The different kinds of __builtin_va_list types defined by
+ /// The different kinds of __builtin_va_list types defined by
/// the target implementation.
enum BuiltinVaListKind {
/// typedef char* __builtin_va_list;
@@ -193,7 +222,7 @@ protected:
WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType,
ProcessIDType;
- /// \brief Whether Objective-C's built-in boolean type should be signed char.
+ /// Whether Objective-C's built-in boolean type should be signed char.
///
/// Otherwise, when this flag is not set, the normal built-in boolean type is
/// used.
@@ -206,7 +235,7 @@ protected:
/// boundary.
unsigned UseBitFieldTypeAlignment : 1;
- /// \brief Whether zero length bitfields (e.g., int : 0;) force alignment of
+ /// Whether zero length bitfields (e.g., int : 0;) force alignment of
/// the next bitfield.
///
/// If the alignment of the zero length bitfield is greater than the member
@@ -214,14 +243,14 @@ protected:
/// zero-length bitfield.
unsigned UseZeroLengthBitfieldAlignment : 1;
- /// \brief Whether explicit bit field alignment attributes are honored.
+ /// Whether explicit bit field alignment attributes are honored.
unsigned UseExplicitBitFieldAlignment : 1;
/// If non-zero, specifies a fixed alignment value for bitfields that follow
/// zero length bitfield, regardless of the zero length bitfield type.
unsigned ZeroLengthBitfieldBoundary;
- /// \brief Specify if mangling based on address space map should be used or
+ /// Specify if mangling based on address space map should be used or
/// not for language specific address spaces
bool UseAddrSpaceMapMangling;
@@ -283,30 +312,30 @@ public:
}
}
- /// \brief Return the width (in bits) of the specified integer type enum.
+ /// Return the width (in bits) of the specified integer type enum.
///
/// For example, SignedInt -> getIntWidth().
unsigned getTypeWidth(IntType T) const;
- /// \brief Return integer type with specified width.
+ /// Return integer type with specified width.
virtual IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
- /// \brief Return the smallest integer type with at least the specified width.
+ /// Return the smallest integer type with at least the specified width.
virtual IntType getLeastIntTypeByWidth(unsigned BitWidth,
bool IsSigned) const;
- /// \brief Return floating point type with specified width.
+ /// Return floating point type with specified width.
RealType getRealTypeByWidth(unsigned BitWidth) const;
- /// \brief Return the alignment (in bits) of the specified integer type enum.
+ /// Return the alignment (in bits) of the specified integer type enum.
///
/// For example, SignedInt -> getIntAlign().
unsigned getTypeAlign(IntType T) const;
- /// \brief Returns true if the type is signed; false otherwise.
+ /// Returns true if the type is signed; false otherwise.
static bool isTypeSigned(IntType T);
- /// \brief Return the width of pointers on this target, for the
+ /// Return the width of pointers on this target, for the
/// specified address space.
uint64_t getPointerWidth(unsigned AddrSpace) const {
return AddrSpace == 0 ? PointerWidth : getPointerWidthV(AddrSpace);
@@ -315,29 +344,29 @@ public:
return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
}
- /// \brief Return the maximum width of pointers on this target.
+ /// Return the maximum width of pointers on this target.
virtual uint64_t getMaxPointerWidth() const {
return PointerWidth;
}
- /// \brief Get integer value for null pointer.
+ /// Get integer value for null pointer.
/// \param AddrSpace address space of pointee in source language.
virtual uint64_t getNullPointerValue(LangAS AddrSpace) const { return 0; }
- /// \brief Return the size of '_Bool' and C++ 'bool' for this target, in bits.
+ /// Return the size of '_Bool' and C++ 'bool' for this target, in bits.
unsigned getBoolWidth() const { return BoolWidth; }
- /// \brief Return the alignment of '_Bool' and C++ 'bool' for this target.
+ /// Return the alignment of '_Bool' and C++ 'bool' for this target.
unsigned getBoolAlign() const { return BoolAlign; }
unsigned getCharWidth() const { return 8; } // FIXME
unsigned getCharAlign() const { return 8; } // FIXME
- /// \brief Return the size of 'signed short' and 'unsigned short' for this
+ /// Return the size of 'signed short' and 'unsigned short' for this
/// target, in bits.
unsigned getShortWidth() const { return 16; } // FIXME
- /// \brief Return the alignment of 'signed short' and 'unsigned short' for
+ /// Return the alignment of 'signed short' and 'unsigned short' for
/// this target.
unsigned getShortAlign() const { return 16; } // FIXME
@@ -356,19 +385,135 @@ public:
unsigned getLongLongWidth() const { return LongLongWidth; }
unsigned getLongLongAlign() const { return LongLongAlign; }
- /// \brief Determine whether the __int128 type is supported on this target.
+ /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and
+ /// 'unsigned short _Accum' for this target, in bits.
+ unsigned getShortAccumWidth() const { return ShortAccumWidth; }
+ unsigned getShortAccumAlign() const { return ShortAccumAlign; }
+
+ /// getAccumWidth/Align - Return the size of 'signed _Accum' and
+ /// 'unsigned _Accum' for this target, in bits.
+ unsigned getAccumWidth() const { return AccumWidth; }
+ unsigned getAccumAlign() const { return AccumAlign; }
+
+ /// getLongAccumWidth/Align - Return the size of 'signed long _Accum' and
+ /// 'unsigned long _Accum' for this target, in bits.
+ unsigned getLongAccumWidth() const { return LongAccumWidth; }
+ unsigned getLongAccumAlign() const { return LongAccumAlign; }
+
+ /// getShortFractWidth/Align - Return the size of 'signed short _Fract' and
+ /// 'unsigned short _Fract' for this target, in bits.
+ unsigned getShortFractWidth() const { return ShortFractWidth; }
+ unsigned getShortFractAlign() const { return ShortFractAlign; }
+
+ /// getFractWidth/Align - Return the size of 'signed _Fract' and
+ /// 'unsigned _Fract' for this target, in bits.
+ unsigned getFractWidth() const { return FractWidth; }
+ unsigned getFractAlign() const { return FractAlign; }
+
+ /// getLongFractWidth/Align - Return the size of 'signed long _Fract' and
+ /// 'unsigned long _Fract' for this target, in bits.
+ unsigned getLongFractWidth() const { return LongFractWidth; }
+ unsigned getLongFractAlign() const { return LongFractAlign; }
+
+ /// getShortAccumScale/IBits - Return the number of fractional/integral bits
+ /// in a 'signed short _Accum' type.
+ unsigned getShortAccumScale() const { return ShortAccumScale; }
+ unsigned getShortAccumIBits() const {
+ return ShortAccumWidth - ShortAccumScale - 1;
+ }
+
+ /// getAccumScale/IBits - Return the number of fractional/integral bits
+ /// in a 'signed _Accum' type.
+ unsigned getAccumScale() const { return AccumScale; }
+ unsigned getAccumIBits() const { return AccumWidth - AccumScale - 1; }
+
+ /// getLongAccumScale/IBits - Return the number of fractional/integral bits
+ /// in a 'signed long _Accum' type.
+ unsigned getLongAccumScale() const { return LongAccumScale; }
+ unsigned getLongAccumIBits() const {
+ return LongAccumWidth - LongAccumScale - 1;
+ }
+
+ /// getUnsignedShortAccumScale/IBits - Return the number of
+ /// fractional/integral bits in a 'unsigned short _Accum' type.
+ unsigned getUnsignedShortAccumScale() const {
+ return PaddingOnUnsignedFixedPoint ? ShortAccumScale : ShortAccumScale + 1;
+ }
+ unsigned getUnsignedShortAccumIBits() const {
+ return PaddingOnUnsignedFixedPoint
+ ? getShortAccumIBits()
+ : ShortAccumWidth - getUnsignedShortAccumScale();
+ }
+
+ /// getUnsignedAccumScale/IBits - Return the number of fractional/integral
+ /// bits in a 'unsigned _Accum' type.
+ unsigned getUnsignedAccumScale() const {
+ return PaddingOnUnsignedFixedPoint ? AccumScale : AccumScale + 1;
+ }
+ unsigned getUnsignedAccumIBits() const {
+ return PaddingOnUnsignedFixedPoint ? getAccumIBits()
+ : AccumWidth - getUnsignedAccumScale();
+ }
+
+ /// getUnsignedLongAccumScale/IBits - Return the number of fractional/integral
+ /// bits in a 'unsigned long _Accum' type.
+ unsigned getUnsignedLongAccumScale() const {
+ return PaddingOnUnsignedFixedPoint ? LongAccumScale : LongAccumScale + 1;
+ }
+ unsigned getUnsignedLongAccumIBits() const {
+ return PaddingOnUnsignedFixedPoint
+ ? getLongAccumIBits()
+ : LongAccumWidth - getUnsignedLongAccumScale();
+ }
+
+ /// getShortFractScale - Return the number of fractional bits
+ /// in a 'signed short _Fract' type.
+ unsigned getShortFractScale() const { return ShortFractWidth - 1; }
+
+ /// getFractScale - Return the number of fractional bits
+ /// in a 'signed _Fract' type.
+ unsigned getFractScale() const { return FractWidth - 1; }
+
+ /// getLongFractScale - Return the number of fractional bits
+ /// in a 'signed long _Fract' type.
+ unsigned getLongFractScale() const { return LongFractWidth - 1; }
+
+ /// getUnsignedShortFractScale - Return the number of fractional bits
+ /// in a 'unsigned short _Fract' type.
+ unsigned getUnsignedShortFractScale() const {
+ return PaddingOnUnsignedFixedPoint ? getShortFractScale()
+ : getShortFractScale() + 1;
+ }
+
+ /// getUnsignedFractScale - Return the number of fractional bits
+ /// in a 'unsigned _Fract' type.
+ unsigned getUnsignedFractScale() const {
+ return PaddingOnUnsignedFixedPoint ? getFractScale() : getFractScale() + 1;
+ }
+
+ /// getUnsignedLongFractScale - Return the number of fractional bits
+ /// in a 'unsigned long _Fract' type.
+ unsigned getUnsignedLongFractScale() const {
+ return PaddingOnUnsignedFixedPoint ? getLongFractScale()
+ : getLongFractScale() + 1;
+ }
+
+ /// Determine whether the __int128 type is supported on this target.
virtual bool hasInt128Type() const {
- return getPointerWidth(0) >= 64;
+ return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128;
} // FIXME
- /// \brief Determine whether the __float128 type is supported on this target.
+ /// Determine whether _Float16 is supported on this target.
+ virtual bool hasLegalHalfType() const { return HasLegalHalfType; }
+
+ /// Determine whether the __float128 type is supported on this target.
virtual bool hasFloat128Type() const { return HasFloat128; }
- /// \brief Return the alignment that is suitable for storing any
+ /// Return the alignment that is suitable for storing any
/// object with a fundamental alignment requirement.
unsigned getSuitableAlign() const { return SuitableAlign; }
- /// \brief Return the default alignment for __attribute__((aligned)) on
+ /// Return the default alignment for __attribute__((aligned)) on
/// this target, to be used if no alignment value is specified.
unsigned getDefaultAlignForAttributeAligned() const {
return DefaultAlignForAttributeAligned;
@@ -431,11 +576,11 @@ public:
return *Float128Format;
}
- /// \brief Return true if the 'long double' type should be mangled like
+ /// Return true if the 'long double' type should be mangled like
/// __float128.
virtual bool useFloat128ManglingForLongDouble() const { return false; }
- /// \brief Return the value for the C99 FLT_EVAL_METHOD macro.
+ /// Return the value for the C99 FLT_EVAL_METHOD macro.
virtual unsigned getFloatEvalMethod() const { return 0; }
// getLargeArrayMinWidth/Align - Return the minimum array size that is
@@ -443,16 +588,16 @@ public:
unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; }
unsigned getLargeArrayAlign() const { return LargeArrayAlign; }
- /// \brief Return the maximum width lock-free atomic operation which will
+ /// Return the maximum width lock-free atomic operation which will
/// ever be supported for the given target
unsigned getMaxAtomicPromoteWidth() const { return MaxAtomicPromoteWidth; }
- /// \brief Return the maximum width lock-free atomic operation which can be
+ /// Return the maximum width lock-free atomic operation which can be
/// inlined given the supported features of the given target.
unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; }
- /// \brief Set the maximum inline or promote width lock-free atomic operation
+ /// Set the maximum inline or promote width lock-free atomic operation
/// for the given target.
virtual void setMaxAtomicWidth() {}
- /// \brief Returns true if the given target supports lock-free atomic
+ /// Returns true if the given target supports lock-free atomic
/// operations at the specified width and alignment.
virtual bool hasBuiltinAtomic(uint64_t AtomicSizeInBits,
uint64_t AlignmentInBits) const {
@@ -462,14 +607,14 @@ public:
llvm::isPowerOf2_64(AtomicSizeInBits / getCharWidth()));
}
- /// \brief Return the maximum vector alignment supported for the given target.
+ /// Return the maximum vector alignment supported for the given target.
unsigned getMaxVectorAlign() const { return MaxVectorAlign; }
- /// \brief Return default simd alignment for the given target. Generally, this
+ /// Return default simd alignment for the given target. Generally, this
/// value is type-specific, but this alignment can be used for most of the
/// types for the given target.
unsigned getSimdDefaultAlign() const { return SimdDefaultAlign; }
- /// \brief Return the size of intmax_t and uintmax_t for this target, in bits.
+ /// Return the size of intmax_t and uintmax_t for this target, in bits.
unsigned getIntMaxTWidth() const {
return getTypeWidth(IntMaxType);
}
@@ -477,7 +622,7 @@ public:
// Return the size of unwind_word for this target.
virtual unsigned getUnwindWordWidth() const { return getPointerWidth(0); }
- /// \brief Return the "preferred" register width on this target.
+ /// Return the "preferred" register width on this target.
virtual unsigned getRegisterWidth() const {
// Currently we assume the register width on the target matches the pointer
// width, we can introduce a new variable for this if/when some target wants
@@ -485,12 +630,12 @@ public:
return PointerWidth;
}
- /// \brief Returns the name of the mcount instrumentation function.
+ /// Returns the name of the mcount instrumentation function.
const char *getMCountName() const {
return MCountName;
}
- /// \brief Check if the Objective-C built-in boolean type should be signed
+ /// Check if the Objective-C built-in boolean type should be signed
/// char.
///
/// Otherwise, if this returns false, the normal built-in boolean type
@@ -502,58 +647,58 @@ public:
UseSignedCharForObjCBool = false;
}
- /// \brief Check whether the alignment of bit-field types is respected
+ /// Check whether the alignment of bit-field types is respected
/// when laying out structures.
bool useBitFieldTypeAlignment() const {
return UseBitFieldTypeAlignment;
}
- /// \brief Check whether zero length bitfields should force alignment of
+ /// Check whether zero length bitfields should force alignment of
/// the next member.
bool useZeroLengthBitfieldAlignment() const {
return UseZeroLengthBitfieldAlignment;
}
- /// \brief Get the fixed alignment value in bits for a member that follows
+ /// Get the fixed alignment value in bits for a member that follows
/// a zero length bitfield.
unsigned getZeroLengthBitfieldBoundary() const {
return ZeroLengthBitfieldBoundary;
}
- /// \brief Check whether explicit bitfield alignment attributes should be
+ /// Check whether explicit bitfield alignment attributes should be
// honored, as in "__attribute__((aligned(2))) int b : 1;".
bool useExplicitBitFieldAlignment() const {
return UseExplicitBitFieldAlignment;
}
- /// \brief Check whether this target support '\#pragma options align=mac68k'.
+ /// Check whether this target support '\#pragma options align=mac68k'.
bool hasAlignMac68kSupport() const {
return HasAlignMac68kSupport;
}
- /// \brief Return the user string for the specified integer type enum.
+ /// Return the user string for the specified integer type enum.
///
/// For example, SignedShort -> "short".
static const char *getTypeName(IntType T);
- /// \brief Return the constant suffix for the specified integer type enum.
+ /// Return the constant suffix for the specified integer type enum.
///
/// For example, SignedLong -> "L".
const char *getTypeConstantSuffix(IntType T) const;
- /// \brief Return the printf format modifier for the specified
+ /// Return the printf format modifier for the specified
/// integer type enum.
///
/// For example, SignedLong -> "l".
static const char *getTypeFormatModifier(IntType T);
- /// \brief Check whether the given real type should use the "fpret" flavor of
+ /// Check whether the given real type should use the "fpret" flavor of
/// Objective-C message passing on this target.
bool useObjCFPRetForRealType(RealType T) const {
return RealTypeUsesObjCFPRet & (1 << T);
}
- /// \brief Check whether _Complex long double should use the "fp2ret" flavor
+ /// Check whether _Complex long double should use the "fp2ret" flavor
/// of Objective-C message passing on this target.
bool useObjCFP2RetForComplexLongDouble() const {
return ComplexLongDoubleUsesFP2Ret;
@@ -567,7 +712,7 @@ public:
return true;
}
- /// \brief Specify if mangling based on address space map should be used or
+ /// Specify if mangling based on address space map should be used or
/// not for language specific address spaces
bool useAddressSpaceMapMangling() const {
return UseAddrSpaceMapMangling;
@@ -575,7 +720,7 @@ public:
///===---- Other target property query methods --------------------------===//
- /// \brief Appends the target-specific \#define values for this
+ /// Appends the target-specific \#define values for this
/// target set to the specified buffer.
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const = 0;
@@ -593,7 +738,7 @@ public:
/// idea to avoid optimizing based on that undef behavior.
virtual bool isCLZForZeroUndef() const { return true; }
- /// \brief Returns the kind of __builtin_va_list type that should be used
+ /// Returns the kind of __builtin_va_list type that should be used
/// with this target.
virtual BuiltinVaListKind getBuiltinVaListKind() const = 0;
@@ -604,28 +749,34 @@ public:
/// Returns true for RenderScript.
bool isRenderScriptTarget() const { return IsRenderScriptTarget; }
- /// \brief Returns whether the passed in string is a valid clobber in an
+ /// Returns whether the passed in string is a valid clobber in an
/// inline asm statement.
///
/// This is used by Sema.
bool isValidClobber(StringRef Name) const;
- /// \brief Returns whether the passed in string is a valid register name
+ /// Returns whether the passed in string is a valid register name
/// according to GCC.
///
/// This is used by Sema for inline asm statements.
- bool isValidGCCRegisterName(StringRef Name) const;
+ virtual bool isValidGCCRegisterName(StringRef Name) const;
- /// \brief Returns the "normalized" GCC register name.
+ /// Returns the "normalized" GCC register name.
///
/// ReturnCannonical true will return the register name without any additions
/// such as "{}" or "%" in it's canonical form, for example:
/// ReturnCanonical = true and Name = "rax", will return "ax".
StringRef getNormalizedGCCRegisterName(StringRef Name,
bool ReturnCanonical = false) const;
-
- virtual StringRef getConstraintRegister(const StringRef &Constraint,
- const StringRef &Expression) const {
+
+ /// Extracts a register from the passed constraint (if it is a
+ /// single-register constraint) and the asm label expression related to a
+ /// variable in the input or output list of an inline asm statement.
+ ///
+ /// This function is used by Sema in order to diagnose conflicts between
+ /// the clobber list and the input/output lists.
+ virtual StringRef getConstraintRegister(StringRef Constraint,
+ StringRef Expression) const {
return "";
}
@@ -663,11 +814,11 @@ public:
bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; }
bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; }
- /// \brief Return true if this output operand has a matching
+ /// Return true if this output operand has a matching
/// (tied) input operand.
bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; }
- /// \brief Return true if this input operand is a matching
+ /// Return true if this input operand is a matching
/// constraint that ties it to an output operand.
///
/// If this returns true then getTiedOperand will indicate which output
@@ -711,7 +862,7 @@ public:
ImmRange.Max = INT_MAX;
}
- /// \brief Indicate that this is an input operand that is tied to
+ /// Indicate that this is an input operand that is tied to
/// the specified output operand.
///
/// Copy over the various constraint information from the output.
@@ -723,7 +874,7 @@ public:
}
};
- /// \brief Validate register name used for global register variables.
+ /// Validate register name used for global register variables.
///
/// This function returns true if the register passed in RegName can be used
/// for global register variables on this target. In addition, it returns
@@ -777,16 +928,16 @@ public:
return std::string(1, *Constraint);
}
- /// \brief Returns a string of target-specific clobbers, in LLVM format.
+ /// Returns a string of target-specific clobbers, in LLVM format.
virtual const char *getClobbers() const = 0;
- /// \brief Returns true if NaN encoding is IEEE 754-2008.
+ /// Returns true if NaN encoding is IEEE 754-2008.
/// Only MIPS allows a different encoding.
virtual bool isNan2008() const {
return true;
}
- /// \brief Returns the target triple of the primary target.
+ /// Returns the target triple of the primary target.
const llvm::Triple &getTriple() const {
return Triple;
}
@@ -806,7 +957,7 @@ public:
const unsigned RegNum;
};
- /// \brief Does this target support "protected" visibility?
+ /// Does this target support "protected" visibility?
///
/// Any target which dynamic libraries will naturally support
/// something like "default" (meaning that the symbol is visible
@@ -818,7 +969,7 @@ public:
/// either; the entire thing is pretty badly mangled.
virtual bool hasProtectedVisibility() const { return true; }
- /// \brief An optional hook that targets can implement to perform semantic
+ /// An optional hook that targets can implement to perform semantic
/// checking on attribute((section("foo"))) specifiers.
///
/// In this case, "foo" is passed in to be checked. If the section
@@ -833,18 +984,18 @@ public:
return "";
}
- /// \brief Set forced language options.
+ /// Set forced language options.
///
/// Apply changes to the target information with respect to certain
/// language options which change the target configuration and adjust
/// the language based on the target options where applicable.
virtual void adjust(LangOptions &Opts);
- /// \brief Adjust target options based on codegen options.
+ /// Adjust target options based on codegen options.
virtual void adjustTargetOptions(const CodeGenOptions &CGOpts,
TargetOptions &TargetOpts) const {}
- /// \brief Initialize the map with the default set of target features for the
+ /// Initialize the map with the default set of target features for the
/// CPU this should include all legal feature strings on the target.
///
/// \return False on error (invalid features).
@@ -852,41 +1003,44 @@ public:
DiagnosticsEngine &Diags, StringRef CPU,
const std::vector<std::string> &FeatureVec) const;
- /// \brief Get the ABI currently in use.
+ /// Get the ABI currently in use.
virtual StringRef getABI() const { return StringRef(); }
- /// \brief Get the C++ ABI currently in use.
+ /// Get the C++ ABI currently in use.
TargetCXXABI getCXXABI() const {
return TheCXXABI;
}
- /// \brief Target the specified CPU.
+ /// Target the specified CPU.
///
/// \return False on error (invalid CPU name).
virtual bool setCPU(const std::string &Name) {
return false;
}
+ /// Fill a SmallVectorImpl with the valid values to setCPU.
+ virtual void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {}
+
/// brief Determine whether this TargetInfo supports the given CPU name.
virtual bool isValidCPUName(StringRef Name) const {
return true;
}
- /// \brief Use the specified ABI.
+ /// Use the specified ABI.
///
/// \return False on error (invalid ABI name).
virtual bool setABI(const std::string &Name) {
return false;
}
- /// \brief Use the specified unit for FP math.
+ /// Use the specified unit for FP math.
///
/// \return False on error (invalid unit name).
virtual bool setFPMath(StringRef Name) {
return false;
}
- /// \brief Enable or disable a specific target feature;
+ /// Enable or disable a specific target feature;
/// the feature name must be valid.
virtual void setFeatureEnabled(llvm::StringMap<bool> &Features,
StringRef Name,
@@ -894,12 +1048,12 @@ public:
Features[Name] = Enabled;
}
- /// \brief Determine whether this TargetInfo supports the given feature.
+ /// Determine whether this TargetInfo supports the given feature.
virtual bool isValidFeatureName(StringRef Feature) const {
return true;
}
- /// \brief Perform initialization based on the user configured
+ /// Perform initialization based on the user configured
/// set of features (e.g., +sse4).
///
/// The list is guaranteed to have at most one entry per feature.
@@ -915,31 +1069,62 @@ public:
return true;
}
- /// \brief Determine whether the given target has the given feature.
+ /// Determine whether the given target has the given feature.
virtual bool hasFeature(StringRef Feature) const {
return false;
}
- // \brief Validate the contents of the __builtin_cpu_supports(const char*)
+ /// Identify whether this taret supports multiversioning of functions,
+ /// which requires support for cpu_supports and cpu_is functionality.
+ virtual bool supportsMultiVersioning() const { return false; }
+
+ // Validate the contents of the __builtin_cpu_supports(const char*)
// argument.
virtual bool validateCpuSupports(StringRef Name) const { return false; }
- // \brief Validate the contents of the __builtin_cpu_is(const char*)
+ // Return the target-specific priority for features/cpus/vendors so
+ // that they can be properly sorted for checking.
+ virtual unsigned multiVersionSortPriority(StringRef Name) const {
+ return 0;
+ }
+
+ // Validate the contents of the __builtin_cpu_is(const char*)
// argument.
virtual bool validateCpuIs(StringRef Name) const { return false; }
- // \brief Returns maximal number of args passed in registers.
+ // Validate a cpu_dispatch/cpu_specific CPU option, which is a different list
+ // from cpu_is, since it checks via features rather than CPUs directly.
+ virtual bool validateCPUSpecificCPUDispatch(StringRef Name) const {
+ return false;
+ }
+
+ // Get the character to be added for mangling purposes for cpu_specific.
+ virtual char CPUSpecificManglingCharacter(StringRef Name) const {
+ llvm_unreachable(
+ "cpu_specific Multiversioning not implemented on this target");
+ }
+
+ // Get a list of the features that make up the CPU option for
+ // cpu_specific/cpu_dispatch so that it can be passed to llvm as optimization
+ // options.
+ virtual void getCPUSpecificCPUDispatchFeatures(
+ StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {
+ llvm_unreachable(
+ "cpu_specific Multiversioning not implemented on this target");
+ }
+
+ // Returns maximal number of args passed in registers.
unsigned getRegParmMax() const {
assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle");
return RegParmMax;
}
- /// \brief Whether the target supports thread-local storage.
+ /// Whether the target supports thread-local storage.
bool isTLSSupported() const {
return TLSSupported;
}
- /// \brief Return the maximum alignment (in bits) of a TLS variable
+ /// Return the maximum alignment (in bits) of a TLS variable
///
/// Gets the maximum alignment (in bits) of a TLS variable on this target.
/// Returns zero if there is no such constraint.
@@ -947,17 +1132,17 @@ public:
return MaxTLSAlign;
}
- /// \brief Whether target supports variable-length arrays.
+ /// Whether target supports variable-length arrays.
bool isVLASupported() const { return VLASupported; }
- /// \brief Whether the target supports SEH __try.
+ /// Whether the target supports SEH __try.
bool isSEHTrySupported() const {
return getTriple().isOSWindows() &&
(getTriple().getArch() == llvm::Triple::x86 ||
getTriple().getArch() == llvm::Triple::x86_64);
}
- /// \brief Return true if {|} are normal characters in the asm string.
+ /// Return true if {|} are normal characters in the asm string.
///
/// If this returns false (the default), then {abc|xyz} is syntax
/// that says that when compiling for asm variant #0, "abc" should be
@@ -967,7 +1152,7 @@ public:
return NoAsmVariants;
}
- /// \brief Return the register number that __builtin_eh_return_regno would
+ /// Return the register number that __builtin_eh_return_regno would
/// return with the specified argument.
/// This corresponds with TargetLowering's getExceptionPointerRegister
/// and getExceptionSelectorRegister in the backend.
@@ -975,14 +1160,14 @@ public:
return -1;
}
- /// \brief Return the section to use for C++ static initialization functions.
+ /// Return the section to use for C++ static initialization functions.
virtual const char *getStaticInitSectionSpecifier() const {
return nullptr;
}
const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; }
- /// \brief Return an AST address space which can be used opportunistically
+ /// Return an AST address space which can be used opportunistically
/// for constant global memory. It must be possible to convert pointers into
/// this address space to LangAS::Default. If no such address space exists,
/// this may return None, and such optimizations will be disabled.
@@ -990,11 +1175,11 @@ public:
return LangAS::Default;
}
- /// \brief Retrieve the name of the platform as it is used in the
+ /// Retrieve the name of the platform as it is used in the
/// availability attribute.
StringRef getPlatformName() const { return PlatformName; }
- /// \brief Retrieve the minimum desired version of the platform, to
+ /// Retrieve the minimum desired version of the platform, to
/// which the program should be compiled.
VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; }
@@ -1007,7 +1192,7 @@ public:
CCMT_NonMember
};
- /// \brief Gets the default calling convention for the given target and
+ /// Gets the default calling convention for the given target and
/// declaration context.
virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
// Not all targets will specify an explicit calling convention that we can
@@ -1022,7 +1207,7 @@ public:
CCCR_Ignore,
};
- /// \brief Determines whether a given calling convention is valid for the
+ /// Determines whether a given calling convention is valid for the
/// target. A calling convention can either be accepted, produce a warning
/// and be substituted with the default calling convention, or (someday)
/// produce an error (such as using thiscall on a non-instance function).
@@ -1035,31 +1220,47 @@ public:
}
}
+ enum CallingConvKind {
+ CCK_Default,
+ CCK_ClangABI4OrPS4,
+ CCK_MicrosoftWin64
+ };
+
+ virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const;
+
/// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to
/// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.
virtual bool hasSjLjLowering() const {
return false;
}
- /// \brief Whether target allows to overalign ABI-specified preferred alignment
+ /// Check if the target supports CFProtection branch.
+ virtual bool
+ checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const;
+
+ /// Check if the target supports CFProtection branch.
+ virtual bool
+ checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const;
+
+ /// Whether target allows to overalign ABI-specified preferred alignment
virtual bool allowsLargerPreferedTypeAlignment() const { return true; }
- /// \brief Set supported OpenCL extensions and optional core features.
+ /// Set supported OpenCL extensions and optional core features.
virtual void setSupportedOpenCLOpts() {}
- /// \brief Set supported OpenCL extensions as written on command line
+ /// Set supported OpenCL extensions as written on command line
virtual void setOpenCLExtensionOpts() {
for (const auto &Ext : getTargetOpts().OpenCLExtensionsAsWritten) {
getTargetOpts().SupportedOpenCLOptions.support(Ext);
}
}
- /// \brief Get supported OpenCL extensions and optional core features.
+ /// Get supported OpenCL extensions and optional core features.
OpenCLOptions &getSupportedOpenCLOpts() {
return getTargetOpts().SupportedOpenCLOptions;
}
- /// \brief Get const supported OpenCL extensions and optional core features.
+ /// Get const supported OpenCL extensions and optional core features.
const OpenCLOptions &getSupportedOpenCLOpts() const {
return getTargetOpts().SupportedOpenCLOptions;
}
@@ -1075,7 +1276,7 @@ public:
OCLTK_Sampler,
};
- /// \brief Get address space for OpenCL type.
+ /// Get address space for OpenCL type.
virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const;
/// \returns Target specific vtbl ptr address space.
@@ -1093,7 +1294,7 @@ public:
return None;
}
- /// \brief Check the target is valid after it is fully initialized.
+ /// Check the target is valid after it is fully initialized.
virtual bool validateTarget(DiagnosticsEngine &Diags) const {
return true;
}
@@ -1113,6 +1314,11 @@ protected:
virtual ArrayRef<AddlRegName> getGCCAddlRegNames() const {
return None;
}
+
+ private:
+ // Assert the values for the fractional and integral bits for each fixed point
+ // type follow the restrictions given in clause 6.2.6.3 of N1169.
+ void CheckFixedPointBits() const;
};
} // end namespace clang
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index 60becfb8ee76e..31a6742879154 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the clang::TargetOptions class.
+/// Defines the clang::TargetOptions class.
///
//===----------------------------------------------------------------------===//
@@ -22,7 +22,7 @@
namespace clang {
-/// \brief Options for controlling the target.
+/// Options for controlling the target.
class TargetOptions {
public:
/// The name of the target triple to compile for.
@@ -47,7 +47,7 @@ public:
/// If given, the version string of the linker in use.
std::string LinkerVersion;
- /// \brief The list of target specific features to enable or disable, as written on the command line.
+ /// The list of target specific features to enable or disable, as written on the command line.
std::vector<std::string> FeaturesAsWritten;
/// The list of target specific features to enable or disable -- this should
@@ -57,9 +57,16 @@ public:
/// Supported OpenCL extensions and optional core features.
OpenCLOptions SupportedOpenCLOptions;
- /// \brief The list of OpenCL extensions to enable or disable, as written on
+ /// The list of OpenCL extensions to enable or disable, as written on
/// the command line.
std::vector<std::string> OpenCLExtensionsAsWritten;
+
+ /// If given, enables support for __int128_t and __uint128_t types.
+ bool ForceEnableInt128 = false;
+
+ /// \brief If enabled, use 32-bit pointers for accessing const/local/shared
+ /// address space.
+ bool NVPTXUseShortPointers = false;
};
} // end namespace clang
diff --git a/include/clang/Basic/TemplateKinds.h b/include/clang/Basic/TemplateKinds.h
index ac99ad185f330..3b68cba73655b 100644
--- a/include/clang/Basic/TemplateKinds.h
+++ b/include/clang/Basic/TemplateKinds.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the clang::TemplateNameKind enum.
+/// Defines the clang::TemplateNameKind enum.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_TEMPLATEKINDS_H
@@ -16,7 +16,7 @@
namespace clang {
-/// \brief Specifies the kind of template name that an identifier refers to.
+/// Specifies the kind of template name that an identifier refers to.
/// Be careful when changing this: this enumeration is used in diagnostics.
enum TemplateNameKind {
/// The name does not refer to a template.
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 6ae8821a834d0..30cb022f1cba5 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -249,8 +249,10 @@ PUNCTUATOR(caretcaret, "^^")
// KEYMS - This is a keyword if Microsoft extensions are enabled
// KEYNOMS18 - This is a keyword that must never be enabled under
// MSVC <= v18.
-// KEYOPENCL - This is a keyword in OpenCL
-// KEYNOOPENCL - This is a keyword that is not supported in OpenCL
+// KEYOPENCLC - This is a keyword in OpenCL C
+// KEYOPENCLCXX - This is a keyword in OpenCL C++
+// KEYNOOPENCL - This is a keyword that is not supported in OpenCL C
+// nor in OpenCL C++.
// KEYALTIVEC - This is a keyword in AltiVec
// KEYZVECTOR - This is a keyword for the System z vector extensions,
// which are heavily based on AltiVec
@@ -260,6 +262,7 @@ PUNCTUATOR(caretcaret, "^^")
// BOOLSUPPORT - This is a keyword if 'bool' is a built-in type
// HALFSUPPORT - This is a keyword if 'half' is a built-in type
// WCHARSUPPORT - This is a keyword if 'wchar_t' is a built-in type
+// CHAR8SUPPORT - This is a keyword if 'char8_t' is a built-in type
//
KEYWORD(auto , KEYALL)
KEYWORD(break , KEYALL)
@@ -380,9 +383,17 @@ KEYWORD(co_yield , KEYCOROUTINES)
MODULES_KEYWORD(module)
MODULES_KEYWORD(import)
+// C++ char8_t proposal
+KEYWORD(char8_t , CHAR8SUPPORT)
+
// C11 Extension
KEYWORD(_Float16 , KEYALL)
+// ISO/IEC JTC1 SC22 WG14 N1169 Extension
+KEYWORD(_Accum , KEYNOCXX)
+KEYWORD(_Fract , KEYNOCXX)
+KEYWORD(_Sat , KEYNOCXX)
+
// GNU Extensions (in impl-reserved namespace)
KEYWORD(_Decimal32 , KEYALL)
KEYWORD(_Decimal64 , KEYALL)
@@ -398,7 +409,6 @@ TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX)
KEYWORD(__builtin_va_arg , KEYALL)
KEYWORD(__extension__ , KEYALL)
KEYWORD(__float128 , KEYALL)
-ALIAS("_Float128", __float128 , KEYNOCXX)
KEYWORD(__imag , KEYALL)
KEYWORD(__int128 , KEYALL)
KEYWORD(__label__ , KEYALL)
@@ -415,6 +425,7 @@ KEYWORD(typeof , KEYGNU)
KEYWORD(__FUNCDNAME__ , KEYMS)
KEYWORD(__FUNCSIG__ , KEYMS)
KEYWORD(L__FUNCTION__ , KEYMS)
+KEYWORD(L__FUNCSIG__ , KEYMS)
TYPE_TRAIT_1(__is_interface_class, IsInterfaceClass, KEYMS)
TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS)
@@ -464,6 +475,7 @@ TYPE_TRAIT_1(__has_unique_object_representations,
TYPE_TRAIT_N(__is_trivially_constructible, IsTriviallyConstructible, KEYCXX)
TYPE_TRAIT_1(__is_trivially_copyable, IsTriviallyCopyable, KEYCXX)
TYPE_TRAIT_2(__is_trivially_assignable, IsTriviallyAssignable, KEYCXX)
+TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
KEYWORD(__underlying_type , KEYCXX)
// Embarcadero Expression Traits
@@ -521,36 +533,36 @@ KEYWORD(__unaligned , KEYMS)
KEYWORD(__super , KEYMS)
// OpenCL address space qualifiers
-KEYWORD(__global , KEYOPENCL)
-KEYWORD(__local , KEYOPENCL)
-KEYWORD(__constant , KEYOPENCL)
-KEYWORD(__private , KEYOPENCL)
-KEYWORD(__generic , KEYOPENCL)
-ALIAS("global", __global , KEYOPENCL)
-ALIAS("local", __local , KEYOPENCL)
-ALIAS("constant", __constant , KEYOPENCL)
-ALIAS("private", __private , KEYOPENCL)
-ALIAS("generic", __generic , KEYOPENCL)
+KEYWORD(__global , KEYOPENCLC | KEYOPENCLCXX)
+KEYWORD(__local , KEYOPENCLC | KEYOPENCLCXX)
+KEYWORD(__constant , KEYOPENCLC | KEYOPENCLCXX)
+KEYWORD(__private , KEYOPENCLC | KEYOPENCLCXX)
+KEYWORD(__generic , KEYOPENCLC | KEYOPENCLCXX)
+ALIAS("global", __global , KEYOPENCLC)
+ALIAS("local", __local , KEYOPENCLC)
+ALIAS("constant", __constant , KEYOPENCLC)
+ALIAS("private", __private , KEYOPENCLC)
+ALIAS("generic", __generic , KEYOPENCLC)
// OpenCL function qualifiers
-KEYWORD(__kernel , KEYOPENCL)
-ALIAS("kernel", __kernel , KEYOPENCL)
+KEYWORD(__kernel , KEYOPENCLC | KEYOPENCLCXX)
+ALIAS("kernel", __kernel , KEYOPENCLC | KEYOPENCLCXX)
// OpenCL access qualifiers
-KEYWORD(__read_only , KEYOPENCL)
-KEYWORD(__write_only , KEYOPENCL)
-KEYWORD(__read_write , KEYOPENCL)
-ALIAS("read_only", __read_only , KEYOPENCL)
-ALIAS("write_only", __write_only , KEYOPENCL)
-ALIAS("read_write", __read_write , KEYOPENCL)
+KEYWORD(__read_only , KEYOPENCLC | KEYOPENCLCXX)
+KEYWORD(__write_only , KEYOPENCLC | KEYOPENCLCXX)
+KEYWORD(__read_write , KEYOPENCLC | KEYOPENCLCXX)
+ALIAS("read_only", __read_only , KEYOPENCLC | KEYOPENCLCXX)
+ALIAS("write_only", __write_only , KEYOPENCLC | KEYOPENCLCXX)
+ALIAS("read_write", __read_write , KEYOPENCLC | KEYOPENCLCXX)
// OpenCL builtins
-KEYWORD(__builtin_astype , KEYOPENCL)
-KEYWORD(vec_step , KEYOPENCL|KEYALTIVEC|KEYZVECTOR)
-#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCL)
+KEYWORD(__builtin_astype , KEYOPENCLC)
+KEYWORD(vec_step , KEYOPENCLC | KEYALTIVEC | KEYZVECTOR)
+#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC)
#include "clang/Basic/OpenCLImageTypes.def"
// OpenMP Type Traits
KEYWORD(__builtin_omp_required_simd_align, KEYALL)
-KEYWORD(pipe , KEYOPENCL)
+KEYWORD(pipe , KEYOPENCLC)
// Borland Extensions.
KEYWORD(__pascal , KEYALL)
diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h
index f4ecb3eb306f1..fb4b5252b70bc 100644
--- a/include/clang/Basic/TokenKinds.h
+++ b/include/clang/Basic/TokenKinds.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the clang::TokenKind enum and support functions.
+/// Defines the clang::TokenKind enum and support functions.
///
//===----------------------------------------------------------------------===//
@@ -21,14 +21,14 @@ namespace clang {
namespace tok {
-/// \brief Provides a simple uniform namespace for tokens from all C languages.
+/// Provides a simple uniform namespace for tokens from all C languages.
enum TokenKind : unsigned short {
#define TOK(X) X,
#include "clang/Basic/TokenKinds.def"
NUM_TOKENS
};
-/// \brief Provides a namespace for preprocessor keywords which start with a
+/// Provides a namespace for preprocessor keywords which start with a
/// '#' at the beginning of the line.
enum PPKeywordKind {
#define PPKEYWORD(X) pp_##X,
@@ -36,7 +36,7 @@ enum PPKeywordKind {
NUM_PP_KEYWORDS
};
-/// \brief Provides a namespace for Objective-C keywords which start with
+/// Provides a namespace for Objective-C keywords which start with
/// an '@'.
enum ObjCKeywordKind {
#define OBJC1_AT_KEYWORD(X) objc_##X,
@@ -45,18 +45,18 @@ enum ObjCKeywordKind {
NUM_OBJC_KEYWORDS
};
-/// \brief Defines the possible values of an on-off-switch (C99 6.10.6p2).
+/// Defines the possible values of an on-off-switch (C99 6.10.6p2).
enum OnOffSwitch {
OOS_ON, OOS_OFF, OOS_DEFAULT
};
-/// \brief Determines the name of a token as used within the front end.
+/// Determines the name of a token as used within the front end.
///
/// The name of a token will be an internal name (such as "l_square")
/// and should not be used as part of diagnostic messages.
const char *getTokenName(TokenKind Kind) LLVM_READNONE;
-/// \brief Determines the spelling of simple punctuation tokens like
+/// Determines the spelling of simple punctuation tokens like
/// '!' or '%', and returns NULL for literal and annotation tokens.
///
/// This routine only retrieves the "simple" spelling of the token,
@@ -65,16 +65,16 @@ const char *getTokenName(TokenKind Kind) LLVM_READNONE;
/// Preprocessor::getSpelling().
const char *getPunctuatorSpelling(TokenKind Kind) LLVM_READNONE;
-/// \brief Determines the spelling of simple keyword and contextual keyword
+/// Determines the spelling of simple keyword and contextual keyword
/// tokens like 'int' and 'dynamic_cast'. Returns NULL for other token kinds.
const char *getKeywordSpelling(TokenKind Kind) LLVM_READNONE;
-/// \brief Return true if this is a raw identifier or an identifier kind.
+/// Return true if this is a raw identifier or an identifier kind.
inline bool isAnyIdentifier(TokenKind K) {
return (K == tok::identifier) || (K == tok::raw_identifier);
}
-/// \brief Return true if this is a C or C++ string-literal (or
+/// Return true if this is a C or C++ string-literal (or
/// C++11 user-defined-string-literal) token.
inline bool isStringLiteral(TokenKind K) {
return K == tok::string_literal || K == tok::wide_string_literal ||
@@ -82,7 +82,7 @@ inline bool isStringLiteral(TokenKind K) {
K == tok::utf32_string_literal;
}
-/// \brief Return true if this is a "literal" kind, like a numeric
+/// Return true if this is a "literal" kind, like a numeric
/// constant, string, etc.
inline bool isLiteral(TokenKind K) {
return K == tok::numeric_constant || K == tok::char_constant ||
@@ -91,7 +91,7 @@ inline bool isLiteral(TokenKind K) {
isStringLiteral(K) || K == tok::angle_string_literal;
}
-/// \brief Return true if this is any of tok::annot_* kinds.
+/// Return true if this is any of tok::annot_* kinds.
inline bool isAnnotation(TokenKind K) {
#define ANNOTATION(NAME) \
if (K == tok::annot_##NAME) \
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
index 8ecd63f9c3cbb..bdb426834a8cc 100644
--- a/include/clang/Basic/TypeTraits.h
+++ b/include/clang/Basic/TypeTraits.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines enumerations for the type traits support.
+/// Defines enumerations for the type traits support.
///
//===----------------------------------------------------------------------===//
@@ -17,7 +17,7 @@
namespace clang {
- /// \brief Names for traits that operate specifically on types.
+ /// Names for traits that operate specifically on types.
enum TypeTrait {
UTT_HasNothrowAssign,
UTT_HasNothrowMoveAssign,
@@ -80,19 +80,20 @@ namespace clang {
BTT_IsAssignable,
BTT_IsNothrowAssignable,
BTT_IsTriviallyAssignable,
- BTT_Last = BTT_IsTriviallyAssignable,
+ BTT_ReferenceBindsToTemporary,
+ BTT_Last = BTT_ReferenceBindsToTemporary,
TT_IsConstructible,
TT_IsNothrowConstructible,
TT_IsTriviallyConstructible
};
- /// \brief Names for the array type traits.
+ /// Names for the array type traits.
enum ArrayTypeTrait {
ATT_ArrayRank,
ATT_ArrayExtent
};
- /// \brief Names for the "expression or type" traits.
+ /// Names for the "expression or type" traits.
enum UnaryExprOrTypeTrait {
UETT_SizeOf,
UETT_AlignOf,
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
index 57dcf92c3b280..6d625c6ddb80e 100644
--- a/include/clang/Basic/Version.h
+++ b/include/clang/Basic/Version.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines version macros and version-related utility functions
+/// Defines version macros and version-related utility functions
/// for Clang.
///
//===----------------------------------------------------------------------===//
@@ -20,40 +20,40 @@
#include "llvm/ADT/StringRef.h"
namespace clang {
- /// \brief Retrieves the repository path (e.g., Subversion path) that
+ /// Retrieves the repository path (e.g., Subversion path) that
/// identifies the particular Clang branch, tag, or trunk from which this
/// Clang was built.
std::string getClangRepositoryPath();
- /// \brief Retrieves the repository path from which LLVM was built.
+ /// Retrieves the repository path from which LLVM was built.
///
/// This supports LLVM residing in a separate repository from clang.
std::string getLLVMRepositoryPath();
- /// \brief Retrieves the repository revision number (or identifer) from which
+ /// Retrieves the repository revision number (or identifier) from which
/// this Clang was built.
std::string getClangRevision();
- /// \brief Retrieves the repository revision number (or identifer) from which
+ /// Retrieves the repository revision number (or identifier) from which
/// LLVM was built.
///
/// If Clang and LLVM are in the same repository, this returns the same
/// string as getClangRevision.
std::string getLLVMRevision();
- /// \brief Retrieves the full repository version that is an amalgamation of
+ /// Retrieves the full repository version that is an amalgamation of
/// the information in getClangRepositoryPath() and getClangRevision().
std::string getClangFullRepositoryVersion();
- /// \brief Retrieves a string representing the complete clang version,
+ /// Retrieves a string representing the complete clang version,
/// which includes the clang version number, the repository version,
/// and the vendor tag.
std::string getClangFullVersion();
- /// \brief Like getClangFullVersion(), but with a custom tool name.
+ /// Like getClangFullVersion(), but with a custom tool name.
std::string getClangToolFullVersion(llvm::StringRef ToolName);
- /// \brief Retrieves a string representing the complete clang version suitable
+ /// Retrieves a string representing the complete clang version suitable
/// for use in the CPP __VERSION__ macro, which includes the clang version
/// number, the repository version, and the vendor tag.
std::string getClangFullCPPVersion();
diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h
deleted file mode 100644
index da3b01903ed93..0000000000000
--- a/include/clang/Basic/VersionTuple.h
+++ /dev/null
@@ -1,168 +0,0 @@
-//===- VersionTuple.h - Version Number Handling -----------------*- 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 clang::VersionTuple class, which represents a version in
-/// the form major[.minor[.subminor]].
-///
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_BASIC_VERSIONTUPLE_H
-#define LLVM_CLANG_BASIC_VERSIONTUPLE_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/Optional.h"
-#include <string>
-#include <tuple>
-
-namespace clang {
-
-/// \brief Represents a version number in the form major[.minor[.subminor[.build]]].
-class VersionTuple {
- unsigned Major : 31;
-
- unsigned UsesUnderscores : 1;
-
- unsigned Minor : 31;
- unsigned HasMinor : 1;
-
- unsigned Subminor : 31;
- unsigned HasSubminor : 1;
-
- unsigned Build : 31;
- unsigned HasBuild : 1;
-
-public:
- VersionTuple()
- : Major(0), UsesUnderscores(false), Minor(0), HasMinor(false),
- Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {}
-
- explicit VersionTuple(unsigned Major)
- : Major(Major), UsesUnderscores(false), Minor(0), HasMinor(false),
- Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {}
-
- explicit VersionTuple(unsigned Major, unsigned Minor,
- bool UsesUnderscores = false)
- : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor),
- HasMinor(true), Subminor(0), HasSubminor(false), Build(0),
- HasBuild(false) {}
-
- explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor,
- bool UsesUnderscores = false)
- : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor),
- HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(0),
- HasBuild(false) {}
-
- explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor,
- unsigned Build, bool UsesUnderscores = false)
- : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor),
- HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(Build),
- HasBuild(true) {}
-
- /// \brief Determine whether this version information is empty
- /// (e.g., all version components are zero).
- bool empty() const {
- return Major == 0 && Minor == 0 && Subminor == 0 && Build == 0;
- }
-
- /// \brief Retrieve the major version number.
- unsigned getMajor() const { return Major; }
-
- /// \brief Retrieve the minor version number, if provided.
- Optional<unsigned> getMinor() const {
- if (!HasMinor)
- return None;
- return Minor;
- }
-
- /// \brief Retrieve the subminor version number, if provided.
- Optional<unsigned> getSubminor() const {
- if (!HasSubminor)
- return None;
- return Subminor;
- }
-
- /// \brief Retrieve the build version number, if provided.
- Optional<unsigned> getBuild() const {
- if (!HasBuild)
- return None;
- return Build;
- }
-
- bool usesUnderscores() const {
- return UsesUnderscores;
- }
-
- void UseDotAsSeparator() {
- UsesUnderscores = false;
- }
-
- /// \brief Determine if two version numbers are equivalent. If not
- /// provided, minor and subminor version numbers are considered to be zero.
- friend bool operator==(const VersionTuple& X, const VersionTuple &Y) {
- return X.Major == Y.Major && X.Minor == Y.Minor &&
- X.Subminor == Y.Subminor && X.Build == Y.Build;
- }
-
- /// \brief Determine if two version numbers are not equivalent.
- ///
- /// If not provided, minor and subminor version numbers are considered to be
- /// zero.
- friend bool operator!=(const VersionTuple &X, const VersionTuple &Y) {
- return !(X == Y);
- }
-
- /// \brief Determine whether one version number precedes another.
- ///
- /// If not provided, minor and subminor version numbers are considered to be
- /// zero.
- friend bool operator<(const VersionTuple &X, const VersionTuple &Y) {
- return std::tie(X.Major, X.Minor, X.Subminor, X.Build) <
- std::tie(Y.Major, Y.Minor, Y.Subminor, Y.Build);
- }
-
- /// \brief Determine whether one version number follows another.
- ///
- /// If not provided, minor and subminor version numbers are considered to be
- /// zero.
- friend bool operator>(const VersionTuple &X, const VersionTuple &Y) {
- return Y < X;
- }
-
- /// \brief Determine whether one version number precedes or is
- /// equivalent to another.
- ///
- /// If not provided, minor and subminor version numbers are considered to be
- /// zero.
- friend bool operator<=(const VersionTuple &X, const VersionTuple &Y) {
- return !(Y < X);
- }
-
- /// \brief Determine whether one version number follows or is
- /// equivalent to another.
- ///
- /// If not provided, minor and subminor version numbers are considered to be
- /// zero.
- friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) {
- return !(X < Y);
- }
-
- /// \brief Retrieve a string representation of the version number.
- std::string getAsString() const;
-
- /// \brief Try to parse the given string as a version number.
- /// \returns \c true if the string does not match the regular expression
- /// [0-9]+(\.[0-9]+){0,3}
- bool tryParse(StringRef string);
-};
-
-/// \brief Print a version number.
-raw_ostream& operator<<(raw_ostream &Out, const VersionTuple &V);
-
-} // end namespace clang
-#endif // LLVM_CLANG_BASIC_VERSIONTUPLE_H
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
index 245452dd12b57..2480b91123c15 100644
--- a/include/clang/Basic/VirtualFileSystem.h
+++ b/include/clang/Basic/VirtualFileSystem.h
@@ -6,8 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
/// \file
-/// \brief Defines the virtual file system interface vfs::FileSystem.
+/// Defines the virtual file system interface vfs::FileSystem.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H
@@ -15,6 +17,7 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -23,8 +26,6 @@
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
#include <cassert>
#include <cstdint>
#include <ctime>
@@ -39,12 +40,12 @@ namespace llvm {
class MemoryBuffer;
-} // end namespace llvm
+} // namespace llvm
namespace clang {
namespace vfs {
-/// \brief The result of a \p status operation.
+/// The result of a \p status operation.
class Status {
std::string Name;
llvm::sys::fs::UniqueID UID;
@@ -52,14 +53,14 @@ class Status {
uint32_t User;
uint32_t Group;
uint64_t Size;
- llvm::sys::fs::file_type Type;
+ llvm::sys::fs::file_type Type = llvm::sys::fs::file_type::status_error;
llvm::sys::fs::perms Perms;
public:
- bool IsVFSMapped; // FIXME: remove when files support multiple names
+ // FIXME: remove when files support multiple names
+ bool IsVFSMapped = false;
-public:
- Status() : Type(llvm::sys::fs::file_type::status_error) {}
+ Status() = default;
Status(const llvm::sys::fs::file_status &Status);
Status(StringRef Name, llvm::sys::fs::UniqueID UID,
llvm::sys::TimePoint<> MTime, uint32_t User, uint32_t Group,
@@ -71,7 +72,7 @@ public:
static Status copyWithNewName(const llvm::sys::fs::file_status &In,
StringRef NewName);
- /// \brief Returns the name that should be used for this file or directory.
+ /// Returns the name that should be used for this file or directory.
StringRef getName() const { return Name; }
/// @name Status interface from llvm::sys::fs
@@ -97,18 +98,18 @@ public:
/// @}
};
-/// \brief Represents an open file.
+/// Represents an open file.
class File {
public:
- /// \brief Destroy the file after closing it (if open).
+ /// Destroy the file after closing it (if open).
/// Sub-classes should generally call close() inside their destructors. We
/// cannot do that from the base class, since close is virtual.
virtual ~File();
- /// \brief Get the status of the file.
+ /// Get the status of the file.
virtual llvm::ErrorOr<Status> status() = 0;
- /// \brief Get the name of the file
+ /// Get the name of the file
virtual llvm::ErrorOr<std::string> getName() {
if (auto Status = status())
return Status->getName().str();
@@ -116,32 +117,32 @@ public:
return Status.getError();
}
- /// \brief Get the contents of the file as a \p MemoryBuffer.
+ /// Get the contents of the file as a \p MemoryBuffer.
virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBuffer(const Twine &Name, int64_t FileSize = -1,
bool RequiresNullTerminator = true, bool IsVolatile = false) = 0;
- /// \brief Closes the file.
+ /// Closes the file.
virtual std::error_code close() = 0;
};
namespace detail {
-/// \brief An interface for virtual file systems to provide an iterator over the
+/// An interface for virtual file systems to provide an iterator over the
/// (non-recursive) contents of a directory.
struct DirIterImpl {
virtual ~DirIterImpl();
- /// \brief Sets \c CurrentEntry to the next entry in the directory on success,
+ /// Sets \c CurrentEntry to the next entry in the directory on success,
/// or returns a system-defined \c error_code.
virtual std::error_code increment() = 0;
Status CurrentEntry;
};
-} // end namespace detail
+} // namespace detail
-/// \brief An input iterator over the entries in a virtual path, similar to
+/// An input iterator over the entries in a virtual path, similar to
/// llvm::sys::fs::directory_iterator.
class directory_iterator {
std::shared_ptr<detail::DirIterImpl> Impl; // Input iterator semantics on copy
@@ -154,10 +155,10 @@ public:
Impl.reset(); // Normalize the end iterator to Impl == nullptr.
}
- /// \brief Construct an 'end' iterator.
+ /// Construct an 'end' iterator.
directory_iterator() = default;
- /// \brief Equivalent to operator++, with an error code.
+ /// Equivalent to operator++, with an error code.
directory_iterator &increment(std::error_code &EC) {
assert(Impl && "attempting to increment past end");
EC = Impl->increment();
@@ -181,11 +182,11 @@ public:
class FileSystem;
-/// \brief An input iterator over the recursive contents of a virtual path,
+/// An input iterator over the recursive contents of a virtual path,
/// similar to llvm::sys::fs::recursive_directory_iterator.
class recursive_directory_iterator {
- typedef std::stack<directory_iterator, std::vector<directory_iterator>>
- IterState;
+ using IterState =
+ std::stack<directory_iterator, std::vector<directory_iterator>>;
FileSystem *FS;
std::shared_ptr<IterState> State; // Input iterator semantics on copy.
@@ -193,10 +194,11 @@ class recursive_directory_iterator {
public:
recursive_directory_iterator(FileSystem &FS, const Twine &Path,
std::error_code &EC);
- /// \brief Construct an 'end' iterator.
+
+ /// Construct an 'end' iterator.
recursive_directory_iterator() = default;
- /// \brief Equivalent to operator++, with an error code.
+ /// Equivalent to operator++, with an error code.
recursive_directory_iterator &increment(std::error_code &EC);
const Status &operator*() const { return *State->top(); }
@@ -209,21 +211,22 @@ public:
return !(*this == RHS);
}
- /// \brief Gets the current level. Starting path is at level 0.
+ /// Gets the current level. Starting path is at level 0.
int level() const {
- assert(State->size() && "Cannot get level without any iteration state");
+ assert(!State->empty() && "Cannot get level without any iteration state");
return State->size()-1;
}
};
-/// \brief The virtual file system interface.
+/// The virtual file system interface.
class FileSystem : public llvm::ThreadSafeRefCountedBase<FileSystem> {
public:
virtual ~FileSystem();
- /// \brief Get the status of the entry at \p Path, if one exists.
+ /// Get the status of the entry at \p Path, if one exists.
virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0;
- /// \brief Get a \p File object for the file at \p Path, if one exists.
+
+ /// Get a \p File object for the file at \p Path, if one exists.
virtual llvm::ErrorOr<std::unique_ptr<File>>
openFileForRead(const Twine &Path) = 0;
@@ -233,7 +236,7 @@ public:
getBufferForFile(const Twine &Name, int64_t FileSize = -1,
bool RequiresNullTerminator = true, bool IsVolatile = false);
- /// \brief Get a directory_iterator for \p Dir.
+ /// Get a directory_iterator for \p Dir.
/// \note The 'end' iterator is directory_iterator().
virtual directory_iterator dir_begin(const Twine &Dir,
std::error_code &EC) = 0;
@@ -241,9 +244,16 @@ public:
/// Set the working directory. This will affect all following operations on
/// this file system and may propagate down for nested file systems.
virtual std::error_code setCurrentWorkingDirectory(const Twine &Path) = 0;
+
/// Get the working directory of this file system.
virtual llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const = 0;
+ /// Gets real path of \p Path e.g. collapse all . and .. patterns, resolve
+ /// symlinks. For real file system, this uses `llvm::sys::fs::real_path`.
+ /// This returns errc::operation_not_permitted if not implemented by subclass.
+ virtual std::error_code getRealPath(const Twine &Path,
+ SmallVectorImpl<char> &Output) const;
+
/// Check whether a file exists. Provided for convenience.
bool exists(const Twine &Path);
@@ -261,11 +271,11 @@ public:
std::error_code makeAbsolute(SmallVectorImpl<char> &Path) const;
};
-/// \brief Gets an \p vfs::FileSystem for the 'real' file system, as seen by
+/// Gets an \p vfs::FileSystem for the 'real' file system, as seen by
/// the operating system.
IntrusiveRefCntPtr<FileSystem> getRealFileSystem();
-/// \brief A file system that allows overlaying one \p AbstractFileSystem on top
+/// A file system that allows overlaying one \p AbstractFileSystem on top
/// of another.
///
/// Consists of a stack of >=1 \p FileSystem objects, which are treated as being
@@ -276,14 +286,16 @@ IntrusiveRefCntPtr<FileSystem> getRealFileSystem();
/// that exists in more than one file system, the file in the top-most file
/// system overrides the other(s).
class OverlayFileSystem : public FileSystem {
- typedef SmallVector<IntrusiveRefCntPtr<FileSystem>, 1> FileSystemList;
- /// \brief The stack of file systems, implemented as a list in order of
+ using FileSystemList = SmallVector<IntrusiveRefCntPtr<FileSystem>, 1>;
+
+ /// The stack of file systems, implemented as a list in order of
/// their addition.
FileSystemList FSList;
public:
OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> Base);
- /// \brief Pushes a file system on top of the stack.
+
+ /// Pushes a file system on top of the stack.
void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS);
llvm::ErrorOr<Status> status(const Twine &Path) override;
@@ -292,22 +304,27 @@ public:
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override;
std::error_code setCurrentWorkingDirectory(const Twine &Path) override;
+ std::error_code getRealPath(const Twine &Path,
+ SmallVectorImpl<char> &Output) const override;
+
+ using iterator = FileSystemList::reverse_iterator;
+ using const_iterator = FileSystemList::const_reverse_iterator;
- typedef FileSystemList::reverse_iterator iterator;
-
- /// \brief Get an iterator pointing to the most recently added file system.
+ /// Get an iterator pointing to the most recently added file system.
iterator overlays_begin() { return FSList.rbegin(); }
+ const_iterator overlays_begin() const { return FSList.rbegin(); }
- /// \brief Get an iterator pointing one-past the least recently added file
+ /// Get an iterator pointing one-past the least recently added file
/// system.
iterator overlays_end() { return FSList.rend(); }
+ const_iterator overlays_end() const { return FSList.rend(); }
};
namespace detail {
class InMemoryDirectory;
-} // end namespace detail
+} // namespace detail
/// An in-memory file system.
class InMemoryFileSystem : public FileSystem {
@@ -330,6 +347,7 @@ public:
Optional<uint32_t> User = None, Optional<uint32_t> Group = None,
Optional<llvm::sys::fs::file_type> Type = None,
Optional<llvm::sys::fs::perms> Perms = None);
+
/// Add a buffer to the VFS with a path. The VFS does not own the buffer.
/// If present, User, Group, Type and Perms apply to the newly-created file
/// or directory.
@@ -344,6 +362,7 @@ public:
Optional<llvm::sys::fs::perms> Perms = None);
std::string toString() const;
+
/// Return true if this file system normalizes . and .. in paths.
bool useNormalizedPaths() const { return UseNormalizedPaths; }
@@ -351,16 +370,26 @@ public:
llvm::ErrorOr<std::unique_ptr<File>>
openFileForRead(const Twine &Path) override;
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
+
llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
return WorkingDirectory;
}
+ /// Canonicalizes \p Path by combining with the current working
+ /// directory and normalizing the path (e.g. remove dots). If the current
+ /// working directory is not set, this returns errc::operation_not_permitted.
+ ///
+ /// This doesn't resolve symlinks as they are not supported in in-memory file
+ /// system.
+ std::error_code getRealPath(const Twine &Path,
+ SmallVectorImpl<char> &Output) const override;
+
std::error_code setCurrentWorkingDirectory(const Twine &Path) override;
};
-/// \brief Get a globally unique ID for a virtual file or directory.
+/// Get a globally unique ID for a virtual file or directory.
llvm::sys::fs::UniqueID getNextVirtualUniqueID();
-/// \brief Gets a \p FileSystem for a virtual file system described in YAML
+/// Gets a \p FileSystem for a virtual file system described in YAML
/// format.
IntrusiveRefCntPtr<FileSystem>
getVFSFromYAML(std::unique_ptr<llvm::MemoryBuffer> Buffer,
@@ -376,7 +405,7 @@ struct YAMLVFSEntry {
std::string RPath;
};
-/// \brief Collect all pairs of <virtual path, real path> entries from the
+/// Collect all pairs of <virtual path, real path> entries from the
/// \p YAMLFilePath. This is used by the module dependency collector to forward
/// the entries into the reproducer output VFS YAML file.
void collectVFSFromYAML(
@@ -419,7 +448,7 @@ public:
void write(llvm::raw_ostream &OS);
};
-} // end namespace vfs
-} // end namespace clang
+} // namespace vfs
+} // namespace clang
#endif // LLVM_CLANG_BASIC_VIRTUALFILESYSTEM_H
diff --git a/include/clang/Basic/Visibility.h b/include/clang/Basic/Visibility.h
index cc839d789e7fd..c5ab62436fe0e 100644
--- a/include/clang/Basic/Visibility.h
+++ b/include/clang/Basic/Visibility.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the clang::Visibility enumeration and various utility
+/// Defines the clang::Visibility enumeration and various utility
/// functions.
///
//===----------------------------------------------------------------------===//
@@ -16,10 +16,12 @@
#define LLVM_CLANG_BASIC_VISIBILITY_H
#include "clang/Basic/Linkage.h"
+#include <cassert>
+#include <cstdint>
namespace clang {
-/// \brief Describes the different kinds of visibility that a declaration
+/// Describes the different kinds of visibility that a declaration
/// may have.
///
/// Visibility determines how a declaration interacts with the dynamic
diff --git a/include/clang/Basic/X86Target.def b/include/clang/Basic/X86Target.def
index 21550fe2dd55f..d2d2540e50054 100644
--- a/include/clang/Basic/X86Target.def
+++ b/include/clang/Basic/X86Target.def
@@ -12,6 +12,10 @@
//
//===----------------------------------------------------------------------===//
+#ifndef PROC_WITH_FEAT
+#define PROC_WITH_FEAT(ENUM, STRING, IS64BIT, KEYFEATURE) \
+ PROC(ENUM, STRING, IS64BIT)
+#endif
#ifndef PROC
#define PROC(ENUM, STRING, IS64BIT)
@@ -21,6 +25,18 @@
#define PROC_ALIAS(ENUM, ALIAS)
#endif
+#ifndef FEATURE
+#define FEATURE(ENUM)
+#endif
+
+#ifndef CPU_SPECIFIC
+#define CPU_SPECIFIC(NAME, MANGLING, FEATURES)
+#endif
+
+#ifndef CPU_SPECIFIC_ALIAS
+#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME)
+#endif
+
#define PROC_64_BIT true
#define PROC_32_BIT false
@@ -77,7 +93,7 @@ PROC(Nocona, "nocona", PROC_64_BIT)
/// \name Core
/// Core microarchitecture based processors.
//@{
-PROC(Core2, "core2", PROC_64_BIT)
+PROC_WITH_FEAT(Core2, "core2", PROC_64_BIT, FEATURE_SSSE3)
/// This enumerator, like Yonah, is a bit odd. It is another
/// codename which GCC no longer accepts as an option to -march, but Clang
@@ -89,67 +105,74 @@ PROC(Penryn, "penryn", PROC_64_BIT)
/// \name Atom
/// Atom processors
//@{
-PROC(Bonnell, "bonnell", PROC_64_BIT)
+PROC_WITH_FEAT(Bonnell, "bonnell", PROC_64_BIT, FEATURE_SSSE3)
PROC_ALIAS(Bonnell, "atom")
-PROC(Silvermont, "silvermont", PROC_64_BIT)
+PROC_WITH_FEAT(Silvermont, "silvermont", PROC_64_BIT, FEATURE_SSE4_2)
PROC_ALIAS(Silvermont, "slm")
PROC(Goldmont, "goldmont", PROC_64_BIT)
+PROC(GoldmontPlus, "goldmont-plus", PROC_64_BIT)
+
+PROC(Tremont, "tremont", PROC_64_BIT)
//@}
/// \name Nehalem
/// Nehalem microarchitecture based processors.
-PROC(Nehalem, "nehalem", PROC_64_BIT)
+PROC_WITH_FEAT(Nehalem, "nehalem", PROC_64_BIT, FEATURE_SSE4_2)
PROC_ALIAS(Nehalem, "corei7")
/// \name Westmere
/// Westmere microarchitecture based processors.
-PROC(Westmere, "westmere", PROC_64_BIT)
+PROC_WITH_FEAT(Westmere, "westmere", PROC_64_BIT, FEATURE_PCLMUL)
/// \name Sandy Bridge
/// Sandy Bridge microarchitecture based processors.
-PROC(SandyBridge, "sandybridge", PROC_64_BIT)
+PROC_WITH_FEAT(SandyBridge, "sandybridge", PROC_64_BIT, FEATURE_AVX)
PROC_ALIAS(SandyBridge, "corei7-avx")
/// \name Ivy Bridge
/// Ivy Bridge microarchitecture based processors.
-PROC(IvyBridge, "ivybridge", PROC_64_BIT)
+PROC_WITH_FEAT(IvyBridge, "ivybridge", PROC_64_BIT, FEATURE_AVX)
PROC_ALIAS(IvyBridge, "core-avx-i")
/// \name Haswell
/// Haswell microarchitecture based processors.
-PROC(Haswell, "haswell", PROC_64_BIT)
+PROC_WITH_FEAT(Haswell, "haswell", PROC_64_BIT, FEATURE_AVX2)
PROC_ALIAS(Haswell, "core-avx2")
/// \name Broadwell
/// Broadwell microarchitecture based processors.
-PROC(Broadwell, "broadwell", PROC_64_BIT)
+PROC_WITH_FEAT(Broadwell, "broadwell", PROC_64_BIT, FEATURE_AVX2)
/// \name Skylake Client
/// Skylake client microarchitecture based processors.
-PROC(SkylakeClient, "skylake", PROC_64_BIT)
+PROC_WITH_FEAT(SkylakeClient, "skylake", PROC_64_BIT, FEATURE_AVX2)
/// \name Skylake Server
/// Skylake server microarchitecture based processors.
-PROC(SkylakeServer, "skylake-avx512", PROC_64_BIT)
+PROC_WITH_FEAT(SkylakeServer, "skylake-avx512", PROC_64_BIT, FEATURE_AVX512F)
PROC_ALIAS(SkylakeServer, "skx")
/// \name Cannonlake Client
/// Cannonlake client microarchitecture based processors.
-PROC(Cannonlake, "cannonlake", PROC_64_BIT)
+PROC_WITH_FEAT(Cannonlake, "cannonlake", PROC_64_BIT, FEATURE_AVX512VBMI)
/// \name Icelake Client
/// Icelake client microarchitecture based processors.
-PROC(Icelake, "icelake", PROC_64_BIT)
+PROC(IcelakeClient, "icelake-client", PROC_64_BIT)
+
+/// \name Icelake Server
+/// Icelake server microarchitecture based processors.
+PROC(IcelakeServer, "icelake-server", PROC_64_BIT)
/// \name Knights Landing
/// Knights Landing processor.
-PROC(KNL, "knl", PROC_64_BIT)
+PROC_WITH_FEAT(KNL, "knl", PROC_64_BIT, FEATURE_AVX512F)
/// \name Knights Mill
/// Knights Mill processor.
-PROC(KNM, "knm", PROC_64_BIT)
+PROC_WITH_FEAT(KNM, "knm", PROC_64_BIT, FEATURE_AVX5124FMAPS)
/// \name Lakemont
/// Lakemont microarchitecture based processors.
@@ -186,30 +209,30 @@ PROC(K8SSE3, "k8-sse3", PROC_64_BIT)
PROC_ALIAS(K8SSE3, "athlon64-sse3")
PROC_ALIAS(K8SSE3, "opteron-sse3")
-PROC(AMDFAM10, "amdfam10", PROC_64_BIT)
+PROC_WITH_FEAT(AMDFAM10, "amdfam10", PROC_64_BIT, FEATURE_SSE4_A)
PROC_ALIAS(AMDFAM10, "barcelona")
//@}
/// \name Bobcat
/// Bobcat architecture processors.
//@{
-PROC(BTVER1, "btver1", PROC_64_BIT)
-PROC(BTVER2, "btver2", PROC_64_BIT)
+PROC_WITH_FEAT(BTVER1, "btver1", PROC_64_BIT, FEATURE_SSE4_A)
+PROC_WITH_FEAT(BTVER2, "btver2", PROC_64_BIT, FEATURE_BMI)
//@}
/// \name Bulldozer
/// Bulldozer architecture processors.
//@{
-PROC(BDVER1, "bdver1", PROC_64_BIT)
-PROC(BDVER2, "bdver2", PROC_64_BIT)
-PROC(BDVER3, "bdver3", PROC_64_BIT)
-PROC(BDVER4, "bdver4", PROC_64_BIT)
+PROC_WITH_FEAT(BDVER1, "bdver1", PROC_64_BIT, FEATURE_XOP)
+PROC_WITH_FEAT(BDVER2, "bdver2", PROC_64_BIT, FEATURE_FMA)
+PROC_WITH_FEAT(BDVER3, "bdver3", PROC_64_BIT, FEATURE_FMA)
+PROC_WITH_FEAT(BDVER4, "bdver4", PROC_64_BIT, FEATURE_AVX2)
//@}
/// \name zen
/// Zen architecture processors.
//@{
-PROC(ZNVER1, "znver1", PROC_64_BIT)
+PROC_WITH_FEAT(ZNVER1, "znver1", PROC_64_BIT, FEATURE_AVX2)
//@}
/// This specification is deprecated and will be removed in the future.
@@ -225,8 +248,84 @@ PROC(x86_64, "x86-64", PROC_64_BIT)
PROC(Geode, "geode", PROC_32_BIT)
//@}
-
+// List of CPU Supports features in order. These need to remain in the order
+// required by attribute 'target' checking. Note that not all are supported/
+// prioritized by GCC, so synchronization with GCC's implementation may require
+// changing some existing values.
+FEATURE(FEATURE_CMOV)
+FEATURE(FEATURE_MMX)
+FEATURE(FEATURE_SSE)
+FEATURE(FEATURE_SSE2)
+FEATURE(FEATURE_SSE3)
+FEATURE(FEATURE_SSSE3)
+FEATURE(FEATURE_SSE4_A)
+FEATURE(FEATURE_SSE4_1)
+FEATURE(FEATURE_SSE4_2)
+FEATURE(FEATURE_POPCNT)
+FEATURE(FEATURE_AES)
+FEATURE(FEATURE_PCLMUL)
+FEATURE(FEATURE_AVX)
+FEATURE(FEATURE_BMI)
+FEATURE(FEATURE_FMA4)
+FEATURE(FEATURE_XOP)
+FEATURE(FEATURE_FMA)
+FEATURE(FEATURE_BMI2)
+FEATURE(FEATURE_AVX2)
+FEATURE(FEATURE_AVX512F)
+FEATURE(FEATURE_AVX512VL)
+FEATURE(FEATURE_AVX512BW)
+FEATURE(FEATURE_AVX512DQ)
+FEATURE(FEATURE_AVX512CD)
+FEATURE(FEATURE_AVX512ER)
+FEATURE(FEATURE_AVX512PF)
+FEATURE(FEATURE_AVX512VBMI)
+FEATURE(FEATURE_AVX512IFMA)
+FEATURE(FEATURE_AVX5124VNNIW)
+FEATURE(FEATURE_AVX5124FMAPS)
+FEATURE(FEATURE_AVX512VPOPCNTDQ)
+
+
+// FIXME: When commented out features are supported in LLVM, enable them here.
+CPU_SPECIFIC("generic", 'A', "")
+CPU_SPECIFIC("pentium", 'B', "")
+CPU_SPECIFIC("pentium_pro", 'C', "+cmov")
+CPU_SPECIFIC("pentium_mmx", 'D', "+mmx")
+CPU_SPECIFIC("pentium_ii", 'E', "+cmov,+mmx")
+CPU_SPECIFIC("pentium_iii", 'H', "+cmov,+mmx,+sse")
+CPU_SPECIFIC("pentium_iii_no_xmm_regs", 'H',"+cmov,+sse")
+CPU_SPECIFIC("pentium_4", 'J', "+cmov,+mmx,+sse,+sse2")
+CPU_SPECIFIC("pentium_m", 'K', "+cmov,+mmx,+sse,+sse2")
+CPU_SPECIFIC("pentium_4_sse3", 'L', "+cmov,+mmx,+sse,+sse2,+sse3")
+CPU_SPECIFIC("core_2_duo_ssse3", 'M', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3")
+CPU_SPECIFIC("core_2_duo_sse4_1", 'N', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1")
+CPU_SPECIFIC("atom", 'O', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+movbe")
+CPU_SPECIFIC("atom_sse4_2", 'c', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt")
+CPU_SPECIFIC("core_i7_sse4_2", 'P', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt")
+CPU_SPECIFIC("core_aes_pclmulqdq", 'Q', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt")
+CPU_SPECIFIC("atom_sse4_2_movbe", 'd', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt")
+CPU_SPECIFIC("goldmont", 'i', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt")
+CPU_SPECIFIC("sandybridge", 'R', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt,+avx")
+CPU_SPECIFIC_ALIAS("core_2nd_gen_avx", "sandybridge")
+CPU_SPECIFIC("ivybridge", 'S', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt,+f16c,+avx")
+CPU_SPECIFIC_ALIAS("core_3rd_gen_avx", "ivybridge")
+CPU_SPECIFIC("haswell", 'V', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2")
+CPU_SPECIFIC_ALIAS("core_4th_gen_avx", "haswell")
+CPU_SPECIFIC("core_4th_gen_avx_tsx", 'W', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2")
+CPU_SPECIFIC("broadwell", 'X', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+adx")
+CPU_SPECIFIC_ALIAS("core_5th_gen_avx", "broadwell")
+CPU_SPECIFIC("core_5th_gen_avx_tsx", 'Y', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+adx")
+CPU_SPECIFIC("knl", 'Z', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+avx512f,+adx,+avx512er,+avx512pf,+avx512cd")
+CPU_SPECIFIC_ALIAS("mic_avx512", "knl")
+CPU_SPECIFIC("skylake", 'b', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+adx,+mpx")
+CPU_SPECIFIC( "skylake_avx512", 'a', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+avx512dq,+avx512f,+adx,+avx512cd,+avx512bw,+avx512vl,+clwb")
+CPU_SPECIFIC("cannonlake", 'e', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+avx512dq,+avx512f,+adx,+avx512ifma,+avx512cd,+avx512bw,+avx512vl,+avx512vbmi")
+CPU_SPECIFIC("knm", 'j', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+avx512f,+adx,+avx512er,+avx512pf,+avx512cd,+avx5124fmaps,+avx5124vnniw,+avx512vpopcntdq")
+
+#undef CPU_SPECIFIC_ALIAS
+#undef CPU_SPECIFIC
#undef PROC_64_BIT
#undef PROC_32_BIT
+#undef FEATURE
#undef PROC
#undef PROC_ALIAS
+#undef PROC_WITH_FEAT
diff --git a/include/clang/Basic/XRayInstr.h b/include/clang/Basic/XRayInstr.h
new file mode 100644
index 0000000000000..13c3032a5ccab
--- /dev/null
+++ b/include/clang/Basic/XRayInstr.h
@@ -0,0 +1,70 @@
+//===--- XRayInstr.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Defines the clang::XRayInstrKind enum.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_XRAYINSTR_H
+#define LLVM_CLANG_BASIC_XRAYINSTR_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <cstdint>
+
+namespace clang {
+
+using XRayInstrMask = uint32_t;
+
+namespace XRayInstrKind {
+
+// TODO: Auto-generate these as we add more instrumentation kinds.
+enum XRayInstrOrdinal : XRayInstrMask {
+ XRIO_Function,
+ XRIO_Custom,
+ XRIO_Typed,
+ XRIO_Count
+};
+
+constexpr XRayInstrMask None = 0;
+constexpr XRayInstrMask Function = 1U << XRIO_Function;
+constexpr XRayInstrMask Custom = 1U << XRIO_Custom;
+constexpr XRayInstrMask Typed = 1U << XRIO_Typed;
+constexpr XRayInstrMask All = Function | Custom | Typed;
+
+} // namespace XRayInstrKind
+
+struct XRayInstrSet {
+ bool has(XRayInstrMask K) const {
+ assert(llvm::isPowerOf2_32(K));
+ return Mask & K;
+ }
+
+ bool hasOneOf(XRayInstrMask K) const { return Mask & K; }
+
+ void set(XRayInstrMask K, bool Value) {
+ assert(llvm::isPowerOf2_32(K));
+ Mask = Value ? (Mask | K) : (Mask & ~K);
+ }
+
+ void clear(XRayInstrMask K = XRayInstrKind::All) { Mask &= ~K; }
+
+ bool empty() const { return Mask == 0; }
+
+ XRayInstrMask Mask = 0;
+};
+
+XRayInstrMask parseXRayInstrValue(StringRef Value);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_BASIC_XRAYINSTR_H
diff --git a/include/clang/Basic/XRayLists.h b/include/clang/Basic/XRayLists.h
index 8cfea70e280a9..244b1d533b7ca 100644
--- a/include/clang/Basic/XRayLists.h
+++ b/include/clang/Basic/XRayLists.h
@@ -26,12 +26,13 @@ namespace clang {
class XRayFunctionFilter {
std::unique_ptr<llvm::SpecialCaseList> AlwaysInstrument;
std::unique_ptr<llvm::SpecialCaseList> NeverInstrument;
+ std::unique_ptr<llvm::SpecialCaseList> AttrList;
SourceManager &SM;
public:
XRayFunctionFilter(ArrayRef<std::string> AlwaysInstrumentPaths,
ArrayRef<std::string> NeverInstrumentPaths,
- SourceManager &SM);
+ ArrayRef<std::string> AttrListPaths, SourceManager &SM);
enum class ImbueAttribute {
NONE,
diff --git a/include/clang/Basic/arm_fp16.td b/include/clang/Basic/arm_fp16.td
new file mode 100644
index 0000000000000..bc15a22d84a63
--- /dev/null
+++ b/include/clang/Basic/arm_fp16.td
@@ -0,0 +1,131 @@
+//===--- arm_fp16.td - ARM FP16 compiler interface ------------------------===//
+//
+// 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 TableGen definitions from which the ARM FP16 header
+// file will be generated.
+//
+//===----------------------------------------------------------------------===//
+
+include "arm_neon_incl.td"
+
+// ARMv8.2-A FP16 intrinsics.
+let ArchGuard = "defined(__ARM_FEATURE_FP16_SCALAR_ARITHMETIC) && defined(__aarch64__)" in {
+
+ // Negate
+ def VNEGSH : SInst<"vneg", "ss", "Sh">;
+
+ // Reciprocal/Sqrt
+ def SCALAR_FRECPSH : IInst<"vrecps", "sss", "Sh">;
+ def FSQRTSH : SInst<"vsqrt", "ss", "Sh">;
+ def SCALAR_FRSQRTSH : IInst<"vrsqrts", "sss", "Sh">;
+
+ // Reciprocal Estimate
+ def SCALAR_FRECPEH : IInst<"vrecpe", "ss", "Sh">;
+
+ // Reciprocal Exponent
+ def SCALAR_FRECPXH : IInst<"vrecpx", "ss", "Sh">;
+
+ // Reciprocal Square Root Estimate
+ def SCALAR_FRSQRTEH : IInst<"vrsqrte", "ss", "Sh">;
+
+ // Rounding
+ def FRINTZ_S64H : SInst<"vrnd", "ss", "Sh">;
+ def FRINTA_S64H : SInst<"vrnda", "ss", "Sh">;
+ def FRINTI_S64H : SInst<"vrndi", "ss", "Sh">;
+ def FRINTM_S64H : SInst<"vrndm", "ss", "Sh">;
+ def FRINTN_S64H : SInst<"vrndn", "ss", "Sh">;
+ def FRINTP_S64H : SInst<"vrndp", "ss", "Sh">;
+ def FRINTX_S64H : SInst<"vrndx", "ss", "Sh">;
+
+ // Conversion
+ def SCALAR_SCVTFSH : SInst<"vcvth_f16", "Ys", "silUsUiUl">;
+ def SCALAR_FCVTZSH : SInst<"vcvt_s16", "$s", "Sh">;
+ def SCALAR_FCVTZSH1 : SInst<"vcvt_s32", "Is", "Sh">;
+ def SCALAR_FCVTZSH2 : SInst<"vcvt_s64", "Ls", "Sh">;
+ def SCALAR_FCVTZUH : SInst<"vcvt_u16", "bs", "Sh">;
+ def SCALAR_FCVTZUH1 : SInst<"vcvt_u32", "Us", "Sh">;
+ def SCALAR_FCVTZUH2 : SInst<"vcvt_u64", "Os", "Sh">;
+ def SCALAR_FCVTASH : SInst<"vcvta_s16", "$s", "Sh">;
+ def SCALAR_FCVTASH1 : SInst<"vcvta_s32", "Is", "Sh">;
+ def SCALAR_FCVTASH2 : SInst<"vcvta_s64", "Ls", "Sh">;
+ def SCALAR_FCVTAUH : SInst<"vcvta_u16", "bs", "Sh">;
+ def SCALAR_FCVTAUH1 : SInst<"vcvta_u32", "Us", "Sh">;
+ def SCALAR_FCVTAUH2 : SInst<"vcvta_u64", "Os", "Sh">;
+ def SCALAR_FCVTMSH : SInst<"vcvtm_s16", "$s", "Sh">;
+ def SCALAR_FCVTMSH1 : SInst<"vcvtm_s32", "Is", "Sh">;
+ def SCALAR_FCVTMSH2 : SInst<"vcvtm_s64", "Ls", "Sh">;
+ def SCALAR_FCVTMUH : SInst<"vcvtm_u16", "bs", "Sh">;
+ def SCALAR_FCVTMUH1 : SInst<"vcvtm_u32", "Us", "Sh">;
+ def SCALAR_FCVTMUH2 : SInst<"vcvtm_u64", "Os", "Sh">;
+ def SCALAR_FCVTNSH : SInst<"vcvtn_s16", "$s", "Sh">;
+ def SCALAR_FCVTNSH1 : SInst<"vcvtn_s32", "Is", "Sh">;
+ def SCALAR_FCVTNSH2 : SInst<"vcvtn_s64", "Ls", "Sh">;
+ def SCALAR_FCVTNUH : SInst<"vcvtn_u16", "bs", "Sh">;
+ def SCALAR_FCVTNUH1 : SInst<"vcvtn_u32", "Us", "Sh">;
+ def SCALAR_FCVTNUH2 : SInst<"vcvtn_u64", "Os", "Sh">;
+ def SCALAR_FCVTPSH : SInst<"vcvtp_s16", "$s", "Sh">;
+ def SCALAR_FCVTPSH1 : SInst<"vcvtp_s32", "Is", "Sh">;
+ def SCALAR_FCVTPSH2 : SInst<"vcvtp_s64", "Ls", "Sh">;
+ def SCALAR_FCVTPUH : SInst<"vcvtp_u16", "bs", "Sh">;
+ def SCALAR_FCVTPUH1 : SInst<"vcvtp_u32", "Us", "Sh">;
+ def SCALAR_FCVTPUH2 : SInst<"vcvtp_u64", "Os", "Sh">;
+ let isVCVT_N = 1 in {
+ def SCALAR_SCVTFSHO : SInst<"vcvth_n_f16", "Ysi", "silUsUiUl">;
+ def SCALAR_FCVTZSHO : SInst<"vcvt_n_s16", "$si", "Sh">;
+ def SCALAR_FCVTZSH1O: SInst<"vcvt_n_s32", "Isi", "Sh">;
+ def SCALAR_FCVTZSH2O: SInst<"vcvt_n_s64", "Lsi", "Sh">;
+ def SCALAR_FCVTZUHO : SInst<"vcvt_n_u16", "bsi", "Sh">;
+ def SCALAR_FCVTZUH1O: SInst<"vcvt_n_u32", "Usi", "Sh">;
+ def SCALAR_FCVTZUH2O: SInst<"vcvt_n_u64", "Osi", "Sh">;
+ }
+ // Comparison
+ def SCALAR_CMEQRH : SInst<"vceq", "bss", "Sh">;
+ def SCALAR_CMEQZH : SInst<"vceqz", "bs", "Sh">;
+ def SCALAR_CMGERH : SInst<"vcge", "bss", "Sh">;
+ def SCALAR_CMGEZH : SInst<"vcgez", "bs", "Sh">;
+ def SCALAR_CMGTRH : SInst<"vcgt", "bss", "Sh">;
+ def SCALAR_CMGTZH : SInst<"vcgtz", "bs", "Sh">;
+ def SCALAR_CMLERH : SInst<"vcle", "bss", "Sh">;
+ def SCALAR_CMLEZH : SInst<"vclez", "bs", "Sh">;
+ def SCALAR_CMLTH : SInst<"vclt", "bss", "Sh">;
+ def SCALAR_CMLTZH : SInst<"vcltz", "bs", "Sh">;
+
+ // Absolute Compare Mask Greater Than Or Equal
+ def SCALAR_FACGEH : IInst<"vcage", "bss", "Sh">;
+ def SCALAR_FACLEH : IInst<"vcale", "bss", "Sh">;
+
+ // Absolute Compare Mask Greater Than
+ def SCALAR_FACGT : IInst<"vcagt", "bss", "Sh">;
+ def SCALAR_FACLT : IInst<"vcalt", "bss", "Sh">;
+
+ // Scalar Absolute Value
+ def SCALAR_ABSH : SInst<"vabs", "ss", "Sh">;
+
+ // Scalar Absolute Difference
+ def SCALAR_ABDH: IInst<"vabd", "sss", "Sh">;
+
+ // Add/Sub
+ def VADDSH : SInst<"vadd", "sss", "Sh">;
+ def VSUBHS : SInst<"vsub", "sss", "Sh">;
+
+ // Max/Min
+ def VMAXHS : SInst<"vmax", "sss", "Sh">;
+ def VMINHS : SInst<"vmin", "sss", "Sh">;
+ def FMAXNMHS : SInst<"vmaxnm", "sss", "Sh">;
+ def FMINNMHS : SInst<"vminnm", "sss", "Sh">;
+
+ // Multiplication/Division
+ def VMULHS : SInst<"vmul", "sss", "Sh">;
+ def MULXHS : SInst<"vmulx", "sss", "Sh">;
+ def FDIVHS : SInst<"vdiv", "sss", "Sh">;
+
+ // Vector fused multiply-add operations
+ def VFMAHS : SInst<"vfma", "ssss", "Sh">;
+ def VFMSHS : SInst<"vfms", "ssss", "Sh">;
+}
diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td
index d5c16a91a34f2..d405aac106504 100644
--- a/include/clang/Basic/arm_neon.td
+++ b/include/clang/Basic/arm_neon.td
@@ -11,309 +11,8 @@
// file will be generated. See ARM document DUI0348B.
//
//===----------------------------------------------------------------------===//
-//
-// Each intrinsic is a subclass of the Inst class. An intrinsic can either
-// generate a __builtin_* call or it can expand to a set of generic operations.
-//
-// The operations are subclasses of Operation providing a list of DAGs, the
-// last of which is the return value. The available DAG nodes are documented
-// below.
-//
-//===----------------------------------------------------------------------===//
-
-// The base Operation class. All operations must subclass this.
-class Operation<list<dag> ops=[]> {
- list<dag> Ops = ops;
- bit Unavailable = 0;
-}
-// An operation that only contains a single DAG.
-class Op<dag op> : Operation<[op]>;
-// A shorter version of Operation - takes a list of DAGs. The last of these will
-// be the return value.
-class LOp<list<dag> ops> : Operation<ops>;
-
-// These defs and classes are used internally to implement the SetTheory
-// expansion and should be ignored.
-foreach Index = 0-63 in
- def sv##Index;
-class MaskExpand;
-
-//===----------------------------------------------------------------------===//
-// Available operations
-//===----------------------------------------------------------------------===//
-
-// DAG arguments can either be operations (documented below) or variables.
-// Variables are prefixed with '$'. There are variables for each input argument,
-// with the name $pN, where N starts at zero. So the zero'th argument will be
-// $p0, the first $p1 etc.
-
-// op - Binary or unary operator, depending on the number of arguments. The
-// operator itself is just treated as a raw string and is not checked.
-// example: (op "+", $p0, $p1) -> "__p0 + __p1".
-// (op "-", $p0) -> "-__p0"
-def op;
-// call - Invoke another intrinsic. The input types are type checked and
-// disambiguated. If there is no intrinsic defined that takes
-// the given types (or if there is a type ambiguity) an error is
-// generated at tblgen time. The name of the intrinsic is the raw
-// name as given to the Inst class (not mangled).
-// example: (call "vget_high", $p0) -> "vgetq_high_s16(__p0)"
-// (assuming $p0 has type int16x8_t).
-def call;
-// cast - Perform a cast to a different type. This gets emitted as a static
-// C-style cast. For a pure reinterpret cast (T x = *(T*)&y), use
-// "bitcast".
-//
-// The syntax is (cast MOD* VAL). The last argument is the value to
-// cast, preceded by a sequence of type modifiers. The target type
-// starts off as the type of VAL, and is modified by MOD in sequence.
-// The available modifiers are:
-// - $X - Take the type of parameter/variable X. For example:
-// (cast $p0, $p1) would cast $p1 to the type of $p0.
-// - "R" - The type of the return type.
-// - A typedef string - A NEON or stdint.h type that is then parsed.
-// for example: (cast "uint32x4_t", $p0).
-// - "U" - Make the type unsigned.
-// - "S" - Make the type signed.
-// - "H" - Halve the number of lanes in the type.
-// - "D" - Double the number of lanes in the type.
-// - "8" - Convert type to an equivalent vector of 8-bit signed
-// integers.
-// example: (cast "R", "U", $p0) -> "(uint32x4_t)__p0" (assuming the return
-// value is of type "int32x4_t".
-// (cast $p0, "D", "8", $p1) -> "(int8x16_t)__p1" (assuming __p0
-// has type float64x1_t or any other vector type of 64 bits).
-// (cast "int32_t", $p2) -> "(int32_t)__p2"
-def cast;
-// bitcast - Same as "cast", except a reinterpret-cast is produced:
-// (bitcast "T", $p0) -> "*(T*)&__p0".
-// The VAL argument is saved to a temporary so it can be used
-// as an l-value.
-def bitcast;
-// dup - Take a scalar argument and create a vector by duplicating it into
-// all lanes. The type of the vector is the base type of the intrinsic.
-// example: (dup $p1) -> "(uint32x2_t) {__p1, __p1}" (assuming the base type
-// is uint32x2_t).
-def dup;
-// splat - Take a vector and a lane index, and return a vector of the same type
-// containing repeated instances of the source vector at the lane index.
-// example: (splat $p0, $p1) ->
-// "__builtin_shufflevector(__p0, __p0, __p1, __p1, __p1, __p1)"
-// (assuming __p0 has four elements).
-def splat;
-// save_temp - Create a temporary (local) variable. The variable takes a name
-// based on the zero'th parameter and can be referenced using
-// using that name in subsequent DAGs in the same
-// operation. The scope of a temp is the operation. If a variable
-// with the given name already exists, an error will be given at
-// tblgen time.
-// example: [(save_temp $var, (call "foo", $p0)),
-// (op "+", $var, $p1)] ->
-// "int32x2_t __var = foo(__p0); return __var + __p1;"
-def save_temp;
-// name_replace - Return the name of the current intrinsic with the first
-// argument replaced by the second argument. Raises an error if
-// the first argument does not exist in the intrinsic name.
-// example: (call (name_replace "_high_", "_"), $p0) (to call the non-high
-// version of this intrinsic).
-def name_replace;
-// literal - Create a literal piece of code. The code is treated as a raw
-// string, and must be given a type. The type is a stdint.h or
-// NEON intrinsic type as given to (cast).
-// example: (literal "int32_t", "0")
-def literal;
-// shuffle - Create a vector shuffle. The syntax is (shuffle ARG0, ARG1, MASK).
-// The MASK argument is a set of elements. The elements are generated
-// from the two special defs "mask0" and "mask1". "mask0" expands to
-// the lane indices in sequence for ARG0, and "mask1" expands to
-// the lane indices in sequence for ARG1. They can be used as-is, e.g.
-//
-// (shuffle $p0, $p1, mask0) -> $p0
-// (shuffle $p0, $p1, mask1) -> $p1
-//
-// or, more usefully, they can be manipulated using the SetTheory
-// operators plus some extra operators defined in the NEON emitter.
-// The operators are described below.
-// example: (shuffle $p0, $p1, (add (highhalf mask0), (highhalf mask1))) ->
-// A concatenation of the high halves of the input vectors.
-def shuffle;
-
-// add, interleave, decimate: These set operators are vanilla SetTheory
-// operators and take their normal definition.
-def add;
-def interleave;
-def decimate;
-// rotl - Rotate set left by a number of elements.
-// example: (rotl mask0, 3) -> [3, 4, 5, 6, 0, 1, 2]
-def rotl;
-// rotl - Rotate set right by a number of elements.
-// example: (rotr mask0, 3) -> [4, 5, 6, 0, 1, 2, 3]
-def rotr;
-// highhalf - Take only the high half of the input.
-// example: (highhalf mask0) -> [4, 5, 6, 7] (assuming mask0 had 8 elements)
-def highhalf;
-// highhalf - Take only the low half of the input.
-// example: (lowhalf mask0) -> [0, 1, 2, 3] (assuming mask0 had 8 elements)
-def lowhalf;
-// rev - Perform a variable-width reversal of the elements. The zero'th argument
-// is a width in bits to reverse. The lanes this maps to is determined
-// based on the element width of the underlying type.
-// example: (rev 32, mask0) -> [3, 2, 1, 0, 7, 6, 5, 4] (if 8-bit elements)
-// example: (rev 32, mask0) -> [1, 0, 3, 2] (if 16-bit elements)
-def rev;
-// mask0 - The initial sequence of lanes for shuffle ARG0
-def mask0 : MaskExpand;
-// mask0 - The initial sequence of lanes for shuffle ARG1
-def mask1 : MaskExpand;
-
-def OP_NONE : Operation;
-def OP_UNAVAILABLE : Operation {
- let Unavailable = 1;
-}
-
-//===----------------------------------------------------------------------===//
-// Instruction definitions
-//===----------------------------------------------------------------------===//
-
-// Every intrinsic subclasses "Inst". An intrinsic has a name, a prototype and
-// a sequence of typespecs.
-//
-// The name is the base name of the intrinsic, for example "vget_lane". This is
-// then mangled by the tblgen backend to add type information ("vget_lane_s16").
-//
-// A typespec is a sequence of uppercase characters (modifiers) followed by one
-// lowercase character. A typespec encodes a particular "base type" of the
-// intrinsic.
-//
-// An example typespec is "Qs" - quad-size short - uint16x8_t. The available
-// typespec codes are given below.
-//
-// The string given to an Inst class is a sequence of typespecs. The intrinsic
-// is instantiated for every typespec in the sequence. For example "sdQsQd".
-//
-// The prototype is a string that defines the return type of the intrinsic
-// and the type of each argument. The return type and every argument gets a
-// "modifier" that can change in some way the "base type" of the intrinsic.
-//
-// The modifier 'd' means "default" and does not modify the base type in any
-// way. The available modifiers are given below.
-//
-// Typespecs
-// ---------
-// c: char
-// s: short
-// i: int
-// l: long
-// k: 128-bit long
-// f: float
-// h: half-float
-// d: double
-//
-// Typespec modifiers
-// ------------------
-// S: scalar, only used for function mangling.
-// U: unsigned
-// Q: 128b
-// H: 128b without mangling 'q'
-// P: polynomial
-//
-// Prototype modifiers
-// -------------------
-// prototype: return (arg, arg, ...)
-//
-// v: void
-// t: best-fit integer (int/poly args)
-// x: signed integer (int/float args)
-// u: unsigned integer (int/float args)
-// f: float (int args)
-// F: double (int args)
-// H: half (int args)
-// d: default
-// g: default, ignore 'Q' size modifier.
-// j: default, force 'Q' size modifier.
-// w: double width elements, same num elts
-// n: double width elements, half num elts
-// h: half width elements, double num elts
-// q: half width elements, quad num elts
-// e: half width elements, double num elts, unsigned
-// m: half width elements, same num elts
-// i: constant int
-// l: constant uint64
-// s: scalar of element type
-// z: scalar of half width element type, signed
-// r: scalar of double width element type, signed
-// a: scalar of element type (splat to vector type)
-// b: scalar of unsigned integer/long type (int/float args)
-// $: scalar of signed integer/long type (int/float args)
-// y: scalar of float
-// o: scalar of double
-// k: default elt width, double num elts
-// 2,3,4: array of default vectors
-// B,C,D: array of default elts, force 'Q' size modifier.
-// p: pointer type
-// c: const pointer type
-
-// Every intrinsic subclasses Inst.
-class Inst <string n, string p, string t, Operation o> {
- string Name = n;
- string Prototype = p;
- string Types = t;
- string ArchGuard = "";
-
- Operation Operation = o;
- bit CartesianProductOfTypes = 0;
- bit BigEndianSafe = 0;
- bit isShift = 0;
- bit isScalarShift = 0;
- bit isScalarNarrowShift = 0;
- bit isVCVT_N = 0;
- // For immediate checks: the immediate will be assumed to specify the lane of
- // a Q register. Only used for intrinsics which end up calling polymorphic
- // builtins.
- bit isLaneQ = 0;
-
- // Certain intrinsics have different names than their representative
- // instructions. This field allows us to handle this correctly when we
- // are generating tests.
- string InstName = "";
-
- // Certain intrinsics even though they are not a WOpInst or LOpInst,
- // generate a WOpInst/LOpInst instruction (see below for definition
- // of a WOpInst/LOpInst). For testing purposes we need to know
- // this. Ex: vset_lane which outputs vmov instructions.
- bit isHiddenWInst = 0;
- bit isHiddenLInst = 0;
-}
-
-// The following instruction classes are implemented via builtins.
-// These declarations are used to generate Builtins.def:
-//
-// SInst: Instruction with signed/unsigned suffix (e.g., "s8", "u8", "p8")
-// IInst: Instruction with generic integer suffix (e.g., "i8")
-// WInst: Instruction with only bit size suffix (e.g., "8")
-class SInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {}
-class IInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {}
-class WInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {}
-
-// The following instruction classes are implemented via operators
-// instead of builtins. As such these declarations are only used for
-// the purpose of generating tests.
-//
-// SOpInst: Instruction with signed/unsigned suffix (e.g., "s8",
-// "u8", "p8").
-// IOpInst: Instruction with generic integer suffix (e.g., "i8").
-// WOpInst: Instruction with bit size only suffix (e.g., "8").
-// LOpInst: Logical instruction with no bit size suffix.
-// NoTestOpInst: Intrinsic that has no corresponding instruction.
-class SOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
-class IOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
-class WOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
-class LOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
-class NoTestOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
-//===----------------------------------------------------------------------===//
-// Operations
-//===----------------------------------------------------------------------===//
+include "arm_neon_incl.td"
def OP_ADD : Op<(op "+", $p0, $p1)>;
def OP_ADDL : Op<(op "+", (call "vmovl", $p0), (call "vmovl", $p1))>;
@@ -500,6 +199,13 @@ def OP_SCALAR_HALF_SET_LNQ : Op<(bitcast "float16x8_t",
(bitcast "int16_t", $p0),
(bitcast "int16x8_t", $p1), $p2))>;
+def OP_DOT_LN
+ : Op<(call "vdot", $p0, $p1,
+ (bitcast $p1, (splat(bitcast "uint32x2_t", $p2), $p3)))>;
+def OP_DOT_LNQ
+ : Op<(call "vdot", $p0, $p1,
+ (bitcast $p1, (splat(bitcast "uint32x4_t", $p2), $p3)))>;
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -632,12 +338,24 @@ def VSLI_N : WInst<"vsli_n", "dddi",
// E.3.14 Loads and stores of a single vector
def VLD1 : WInst<"vld1", "dc",
"QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VLD1_X2 : WInst<"vld1_x2", "2c",
+ "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
+def VLD1_X3 : WInst<"vld1_x3", "3c",
+ "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
+def VLD1_X4 : WInst<"vld1_x4", "4c",
+ "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
def VLD1_LANE : WInst<"vld1_lane", "dcdi",
"QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
def VLD1_DUP : WInst<"vld1_dup", "dc",
"QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
def VST1 : WInst<"vst1", "vpd",
"QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
+def VST1_X2 : WInst<"vst1_x2", "vp2",
+ "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
+def VST1_X3 : WInst<"vst1_x3", "vp3",
+ "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
+def VST1_X4 : WInst<"vst1_x4", "vp4",
+ "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">;
def VST1_LANE : WInst<"vst1_lane", "vpdi",
"QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
@@ -646,9 +364,12 @@ def VST1_LANE : WInst<"vst1_lane", "vpdi",
def VLD2 : WInst<"vld2", "2c", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
def VLD3 : WInst<"vld3", "3c", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
def VLD4 : WInst<"vld4", "4c", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">;
-def VLD2_DUP : WInst<"vld2_dup", "2c", "UcUsUiUlcsilhfPcPs">;
-def VLD3_DUP : WInst<"vld3_dup", "3c", "UcUsUiUlcsilhfPcPs">;
-def VLD4_DUP : WInst<"vld4_dup", "4c", "UcUsUiUlcsilhfPcPs">;
+def VLD2_DUP : WInst<"vld2_dup", "2c",
+ "UcUsUiUlcsilhfPcPsQcQfQhQiQlQsQPcQPsQUcQUiQUlQUs">;
+def VLD3_DUP : WInst<"vld3_dup", "3c",
+ "UcUsUiUlcsilhfPcPsQcQfQhQiQlQsQPcQPsQUcQUiQUlQUs">;
+def VLD4_DUP : WInst<"vld4_dup", "4c",
+ "UcUsUiUlcsilhfPcPsQcQfQhQiQlQsQPcQPsQUcQUiQUlQUs">;
def VLD2_LANE : WInst<"vld2_lane", "2c2i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
def VLD3_LANE : WInst<"vld3_lane", "3c3i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
def VLD4_LANE : WInst<"vld4_lane", "4c4i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">;
@@ -698,6 +419,10 @@ def VCOMBINE : NoTestOpInst<"vcombine", "kdd", "csilhfUcUsUiUlPcPs", OP_CONC>;
////////////////////////////////////////////////////////////////////////////////
// E.3.21 Splitting vectors
+// Note that the ARM NEON Reference 2.0 mistakenly document the vget_high_f16()
+// and vget_low_f16() intrinsics as AArch64-only. We (and GCC) support all
+// versions of these intrinsics in both AArch32 and AArch64 architectures. See
+// D45668 for more details.
let InstName = "vmov" in {
def VGET_HIGH : NoTestOpInst<"vget_high", "dk", "csilhfUcUsUiUlPcPs", OP_HI>;
def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>;
@@ -832,6 +557,7 @@ def VREINTERPRET
let ArchGuard = "defined(__ARM_FEATURE_FMA)" in {
def VFMA : SInst<"vfma", "dddd", "fQf">;
def VFMS : SOpInst<"vfms", "dddd", "fQf", OP_FMLS>;
+ def FMLA_N_F32 : SOpInst<"vfma_n", "ddds", "fQf", OP_FMLA_N>;
}
////////////////////////////////////////////////////////////////////////////////
@@ -858,18 +584,15 @@ def ST3 : WInst<"vst3", "vp3", "QUlQldQdPlQPl">;
def ST4 : WInst<"vst4", "vp4", "QUlQldQdPlQPl">;
def LD1_X2 : WInst<"vld1_x2", "2c",
- "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
-def LD3_x3 : WInst<"vld1_x3", "3c",
- "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
-def LD4_x4 : WInst<"vld1_x4", "4c",
- "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
-
-def ST1_X2 : WInst<"vst1_x2", "vp2",
- "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
-def ST1_X3 : WInst<"vst1_x3", "vp3",
- "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
-def ST1_X4 : WInst<"vst1_x4", "vp4",
- "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
+ "dQdPlQPl">;
+def LD1_X3 : WInst<"vld1_x3", "3c",
+ "dQdPlQPl">;
+def LD1_X4 : WInst<"vld1_x4", "4c",
+ "dQdPlQPl">;
+
+def ST1_X2 : WInst<"vst1_x2", "vp2", "dQdPlQPl">;
+def ST1_X3 : WInst<"vst1_x3", "vp3", "dQdPlQPl">;
+def ST1_X4 : WInst<"vst1_x4", "vp4", "dQdPlQPl">;
def LD1_LANE : WInst<"vld1_lane", "dcdi", "dQdPlQPl">;
def LD2_LANE : WInst<"vld2_lane", "2c2i", "lUlQcQUcQPcQlQUldQdPlQPl">;
@@ -881,12 +604,9 @@ def ST3_LANE : WInst<"vst3_lane", "vp3i", "lUlQcQUcQPcQlQUldQdPlQPl">;
def ST4_LANE : WInst<"vst4_lane", "vp4i", "lUlQcQUcQPcQlQUldQdPlQPl">;
def LD1_DUP : WInst<"vld1_dup", "dc", "dQdPlQPl">;
-def LD2_DUP : WInst<"vld2_dup", "2c",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPldPl">;
-def LD3_DUP : WInst<"vld3_dup", "3c",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPldPl">;
-def LD4_DUP : WInst<"vld4_dup", "4c",
- "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPldPl">;
+def LD2_DUP : WInst<"vld2_dup", "2c", "dQdPlQPl">;
+def LD3_DUP : WInst<"vld3_dup", "3c", "dQdPlQPl">;
+def LD4_DUP : WInst<"vld4_dup", "4c", "dQdPlQPl">;
def VLDRQ : WInst<"vldrq", "sc", "Pk">;
def VSTRQ : WInst<"vstrq", "vps", "Pk">;
@@ -922,8 +642,8 @@ def FMLS : SOpInst<"vfms", "dddd", "dQd", OP_FMLS>;
// MUL, MLA, MLS, FMA, FMS definitions with scalar argument
def VMUL_N_A64 : IOpInst<"vmul_n", "dds", "Qd", OP_MUL_N>;
-def FMLA_N : SOpInst<"vfma_n", "ddds", "fQfQd", OP_FMLA_N>;
-def FMLS_N : SOpInst<"vfms_n", "ddds", "fQfQd", OP_FMLS_N>;
+def FMLA_N : SOpInst<"vfma_n", "ddds", "dQd", OP_FMLA_N>;
+def FMLS_N : SOpInst<"vfms_n", "ddds", "fdQfQd", OP_FMLS_N>;
def MLA_N : SOpInst<"vmla_n", "ddds", "Qd", OP_MLA_N>;
def MLS_N : SOpInst<"vmls_n", "ddds", "Qd", OP_MLS_N>;
@@ -1214,7 +934,7 @@ def VEXT_A64 : WInst<"vext", "dddi", "dQdPlQPl">;
////////////////////////////////////////////////////////////////////////////////
// Crypto
-let ArchGuard = "__ARM_FEATURE_CRYPTO" in {
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_CRYPTO)" in {
def AESE : SInst<"vaese", "ddd", "QUc">;
def AESD : SInst<"vaesd", "ddd", "QUc">;
def AESMC : SInst<"vaesmc", "dd", "QUc">;
@@ -1268,6 +988,7 @@ def FRINTP_S32 : SInst<"vrndp", "dd", "fQf">;
def FRINTM_S32 : SInst<"vrndm", "dd", "fQf">;
def FRINTX_S32 : SInst<"vrndx", "dd", "fQf">;
def FRINTZ_S32 : SInst<"vrnd", "dd", "fQf">;
+def FRINTI_S32 : SInst<"vrndi", "dd", "fQf">;
}
let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__) && defined(__ARM_FEATURE_DIRECTED_ROUNDING)" in {
@@ -1277,7 +998,7 @@ def FRINTP_S64 : SInst<"vrndp", "dd", "dQd">;
def FRINTM_S64 : SInst<"vrndm", "dd", "dQd">;
def FRINTX_S64 : SInst<"vrndx", "dd", "dQd">;
def FRINTZ_S64 : SInst<"vrnd", "dd", "dQd">;
-def FRINTI_S64 : SInst<"vrndi", "dd", "fdQfQd">;
+def FRINTI_S64 : SInst<"vrndi", "dd", "dQd">;
}
////////////////////////////////////////////////////////////////////////////////
@@ -1417,6 +1138,12 @@ def SCALAR_FCVTZU_N_U64 : SInst<"vcvt_n_u64", "bsi", "Sd">;
}
////////////////////////////////////////////////////////////////////////////////
+// Scalar Floating-point Round to Integral
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING)" in {
+def SCALAR_FRINTN_S32 : SInst<"vrndn", "ss", "Sf">;
+}
+
+////////////////////////////////////////////////////////////////////////////////
// Scalar Reduce Pairwise Addition (Scalar and Floating Point)
def SCALAR_ADDP : SInst<"vpadd", "sd", "SfSHlSHdSHUl">;
@@ -1664,8 +1391,8 @@ def SCALAR_VDUP_LANE : IInst<"vdup_lane", "sdi", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs
def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "sji", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">;
}
-// ARMv8.2-A FP16 intrinsics.
-let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarch64__)" in {
+// ARMv8.2-A FP16 vector intrinsics for A32/A64.
+let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in {
// ARMv8.2-A FP16 one-operand vector intrinsics.
@@ -1690,20 +1417,20 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarc
def VCVTP_U16 : SInst<"vcvtp_u16", "ud", "hQh">;
// Vector rounding
- def FRINTZH : SInst<"vrnd", "dd", "hQh">;
- def FRINTNH : SInst<"vrndn", "dd", "hQh">;
- def FRINTAH : SInst<"vrnda", "dd", "hQh">;
- def FRINTPH : SInst<"vrndp", "dd", "hQh">;
- def FRINTMH : SInst<"vrndm", "dd", "hQh">;
- def FRINTXH : SInst<"vrndx", "dd", "hQh">;
- def FRINTIH : SInst<"vrndi", "dd", "hQh">;
+ let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in {
+ def FRINTZH : SInst<"vrnd", "dd", "hQh">;
+ def FRINTNH : SInst<"vrndn", "dd", "hQh">;
+ def FRINTAH : SInst<"vrnda", "dd", "hQh">;
+ def FRINTPH : SInst<"vrndp", "dd", "hQh">;
+ def FRINTMH : SInst<"vrndm", "dd", "hQh">;
+ def FRINTXH : SInst<"vrndx", "dd", "hQh">;
+ }
// Misc.
def VABSH : SInst<"vabs", "dd", "hQh">;
def VNEGH : SOpInst<"vneg", "dd", "hQh", OP_NEG>;
def VRECPEH : SInst<"vrecpe", "dd", "hQh">;
def FRSQRTEH : SInst<"vrsqrte", "dd", "hQh">;
- def FSQRTH : SInst<"vsqrt", "dd", "hQh">;
// ARMv8.2-A FP16 two-operands vector intrinsics.
@@ -1714,12 +1441,12 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarc
// Comparison
let InstName = "vacge" in {
- def VCAGEH : SInst<"vcage", "udd", "hQh">;
- def VCALEH : SInst<"vcale", "udd", "hQh">;
+ def VCAGEH : SInst<"vcage", "udd", "hQh">;
+ def VCALEH : SInst<"vcale", "udd", "hQh">;
}
let InstName = "vacgt" in {
def VCAGTH : SInst<"vcagt", "udd", "hQh">;
- def VCALTH : SInst<"vcalt", "udd", "hQh">;
+ def VCALTH : SInst<"vcalt", "udd", "hQh">;
}
def VCEQH : SOpInst<"vceq", "udd", "hQh", OP_EQ>;
def VCGEH : SOpInst<"vcge", "udd", "hQh", OP_GE>;
@@ -1739,23 +1466,20 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarc
// Max/Min
def VMAXH : SInst<"vmax", "ddd", "hQh">;
def VMINH : SInst<"vmin", "ddd", "hQh">;
- def FMAXNMH : SInst<"vmaxnm", "ddd", "hQh">;
- def FMINNMH : SInst<"vminnm", "ddd", "hQh">;
+ let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in {
+ def FMAXNMH : SInst<"vmaxnm", "ddd", "hQh">;
+ def FMINNMH : SInst<"vminnm", "ddd", "hQh">;
+ }
// Multiplication/Division
def VMULH : SOpInst<"vmul", "ddd", "hQh", OP_MUL>;
- def MULXH : SInst<"vmulx", "ddd", "hQh">;
- def FDIVH : IOpInst<"vdiv", "ddd", "hQh", OP_DIV>;
// Pairwise addition
- def VPADDH : SInst<"vpadd", "ddd", "hQh">;
+ def VPADDH : SInst<"vpadd", "ddd", "h">;
// Pairwise Max/Min
- def VPMAXH : SInst<"vpmax", "ddd", "hQh">;
- def VPMINH : SInst<"vpmin", "ddd", "hQh">;
- // Pairwise MaxNum/MinNum
- def FMAXNMPH : SInst<"vpmaxnm", "ddd", "hQh">;
- def FMINNMPH : SInst<"vpminnm", "ddd", "hQh">;
+ def VPMAXH : SInst<"vpmax", "ddd", "h">;
+ def VPMINH : SInst<"vpmin", "ddd", "h">;
// Reciprocal/Sqrt
def VRECPSH : SInst<"vrecps", "ddd", "hQh">;
@@ -1769,6 +1493,63 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarc
// ARMv8.2-A FP16 lane vector intrinsics.
+ // Mul lane
+ def VMUL_LANEH : IOpInst<"vmul_lane", "ddgi", "hQh", OP_MUL_LN>;
+ def VMUL_NH : IOpInst<"vmul_n", "dds", "hQh", OP_MUL_N>;
+
+ // Data processing intrinsics - section 5
+
+ // Logical operations
+ let isHiddenLInst = 1 in
+ def VBSLH : SInst<"vbsl", "dudd", "hQh">;
+
+ // Transposition operations
+ def VZIPH : WInst<"vzip", "2dd", "hQh">;
+ def VUZPH : WInst<"vuzp", "2dd", "hQh">;
+ def VTRNH : WInst<"vtrn", "2dd", "hQh">;
+
+
+ let ArchGuard = "!defined(__aarch64__)" in {
+ // Set all lanes to same value.
+ // Already implemented prior to ARMv8.2-A.
+ def VMOV_NH : WOpInst<"vmov_n", "ds", "hQh", OP_DUP>;
+ def VDUP_NH : WOpInst<"vdup_n", "ds", "hQh", OP_DUP>;
+ def VDUP_LANE1H : WOpInst<"vdup_lane", "dgi", "hQh", OP_DUP_LN>;
+ }
+
+ // Vector Extract
+ def VEXTH : WInst<"vext", "dddi", "hQh">;
+
+ // Reverse vector elements
+ def VREV64H : WOpInst<"vrev64", "dd", "hQh", OP_REV64>;
+}
+
+// ARMv8.2-A FP16 vector intrinsics for A64 only.
+let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarch64__)" in {
+
+ // Vector rounding
+ def FRINTIH : SInst<"vrndi", "dd", "hQh">;
+
+ // Misc.
+ def FSQRTH : SInst<"vsqrt", "dd", "hQh">;
+
+ // Multiplication/Division
+ def MULXH : SInst<"vmulx", "ddd", "hQh">;
+ def FDIVH : IOpInst<"vdiv", "ddd", "hQh", OP_DIV>;
+
+ // Pairwise addition
+ def VPADDH1 : SInst<"vpadd", "ddd", "Qh">;
+
+ // Pairwise Max/Min
+ def VPMAXH1 : SInst<"vpmax", "ddd", "Qh">;
+ def VPMINH1 : SInst<"vpmin", "ddd", "Qh">;
+
+ // Pairwise MaxNum/MinNum
+ def FMAXNMPH : SInst<"vpmaxnm", "ddd", "hQh">;
+ def FMINNMPH : SInst<"vpminnm", "ddd", "hQh">;
+
+ // ARMv8.2-A FP16 lane vector intrinsics.
+
// FMA lane
def VFMA_LANEH : IInst<"vfma_lane", "dddgi", "hQh">;
def VFMA_LANEQH : IInst<"vfma_laneq", "dddji", "hQh">;
@@ -1789,9 +1570,7 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarc
def SCALAR_FMLS_LANEQH : IOpInst<"vfms_laneq", "sssji", "Sh", OP_FMS_LNQ>;
// Mul lane
- def VMUL_LANEH : IOpInst<"vmul_lane", "ddgi", "hQh", OP_MUL_LN>;
def VMUL_LANEQH : IOpInst<"vmul_laneq", "ddji", "hQh", OP_MUL_LN>;
- def VMUL_NH : IOpInst<"vmul_n", "dds", "hQh", OP_MUL_N>;
// Scalar floating point multiply (scalar, by element)
def SCALAR_FMUL_LANEH : IOpInst<"vmul_lane", "ssdi", "Sh", OP_SCALAR_MUL_LN>;
def SCALAR_FMUL_LANEQH : IOpInst<"vmul_laneq", "ssji", "Sh", OP_SCALAR_MUL_LN>;
@@ -1800,11 +1579,9 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarc
def VMULX_LANEH : IOpInst<"vmulx_lane", "ddgi", "hQh", OP_MULX_LN>;
def VMULX_LANEQH : IOpInst<"vmulx_laneq", "ddji", "hQh", OP_MULX_LN>;
def VMULX_NH : IOpInst<"vmulx_n", "dds", "hQh", OP_MULX_N>;
- // TODO: Scalar floating point multiply extended (scalar, by element)
- // Below ones are commented out because they need vmulx_f16(float16_t, float16_t)
- // which will be implemented later with fp16 scalar intrinsic (arm_fp16.h)
- //def SCALAR_FMULX_LANEH : IOpInst<"vmulx_lane", "ssdi", "Sh", OP_SCALAR_MUL_LN>;
- //def SCALAR_FMULX_LANEQH : IOpInst<"vmulx_laneq", "ssji", "Sh", OP_SCALAR_MUL_LN>;
+ // Scalar floating point mulx (scalar, by element)
+ def SCALAR_FMULX_LANEH : IInst<"vmulx_lane", "ssdi", "Sh">;
+ def SCALAR_FMULX_LANEQH : IInst<"vmulx_laneq", "ssji", "Sh">;
// ARMv8.2-A FP16 reduction vector intrinsics.
def VMAXVH : SInst<"vmaxv", "sd", "hQh">;
@@ -1812,29 +1589,6 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarc
def FMAXNMVH : SInst<"vmaxnmv", "sd", "hQh">;
def FMINNMVH : SInst<"vminnmv", "sd", "hQh">;
- // Data processing intrinsics - section 5
-
- // Logical operations
- let isHiddenLInst = 1 in
- def VBSLH : SInst<"vbsl", "dudd", "hQh">;
-
- // Transposition operations
- def VZIPH : WInst<"vzip", "2dd", "hQh">;
- def VUZPH : WInst<"vuzp", "2dd", "hQh">;
- def VTRNH : WInst<"vtrn", "2dd", "hQh">;
-
- // Set all lanes to same value.
- /* Already implemented prior to ARMv8.2-A.
- def VMOV_NH : WOpInst<"vmov_n", "ds", "hQh", OP_DUP>;
- def VDUP_NH : WOpInst<"vdup_n", "ds", "hQh", OP_DUP>;
- def VDUP_LANE1H : WOpInst<"vdup_lane", "dgi", "hQh", OP_DUP_LN>;*/
-
- // Vector Extract
- def VEXTH : WInst<"vext", "dddi", "hQh">;
-
- // Reverse vector elements
- def VREV64H : WOpInst<"vrev64", "dd", "hQh", OP_REV64>;
-
// Permutation
def VTRN1H : SOpInst<"vtrn1", "ddd", "hQh", OP_TRN1>;
def VZIP1H : SOpInst<"vzip1", "ddd", "hQh", OP_ZIP1>;
@@ -1846,3 +1600,13 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarc
def SCALAR_VDUP_LANEH : IInst<"vdup_lane", "sdi", "Sh">;
def SCALAR_VDUP_LANEQH : IInst<"vdup_laneq", "sji", "Sh">;
}
+
+// v8.2-A dot product instructions.
+let ArchGuard = "defined(__ARM_FEATURE_DOTPROD)" in {
+ def DOT : SInst<"vdot", "dd88", "iQiUiQUi">;
+ def DOT_LANE : SOpInst<"vdot_lane", "dd87i", "iUiQiQUi", OP_DOT_LN>;
+}
+let ArchGuard = "defined(__ARM_FEATURE_DOTPROD) && defined(__aarch64__)" in {
+ // Variants indexing into a 128-bit vector are A64 only.
+ def UDOT_LANEQ : SOpInst<"vdot_laneq", "dd89i", "iUiQiQUi", OP_DOT_LNQ>;
+}
diff --git a/include/clang/Basic/arm_neon_incl.td b/include/clang/Basic/arm_neon_incl.td
new file mode 100644
index 0000000000000..46708a52aa3a6
--- /dev/null
+++ b/include/clang/Basic/arm_neon_incl.td
@@ -0,0 +1,316 @@
+//===--- arm_neon_incl.td - ARM NEON compiler interface ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines data structures shared by arm_neon.td and arm_fp16.td.
+// It constains base operation classes, operations, instructions, instruction
+// modifiers, etc.
+//
+//===----------------------------------------------------------------------===//
+//
+// Each intrinsic is a subclass of the Inst class. An intrinsic can either
+// generate a __builtin_* call or it can expand to a set of generic operations.
+//
+// The operations are subclasses of Operation providing a list of DAGs, the
+// last of which is the return value. The available DAG nodes are documented
+// below.
+//
+//===----------------------------------------------------------------------===//
+
+// The base Operation class. All operations must subclass this.
+class Operation<list<dag> ops=[]> {
+ list<dag> Ops = ops;
+ bit Unavailable = 0;
+}
+// An operation that only contains a single DAG.
+class Op<dag op> : Operation<[op]>;
+// A shorter version of Operation - takes a list of DAGs. The last of these will
+// be the return value.
+class LOp<list<dag> ops> : Operation<ops>;
+
+// These defs and classes are used internally to implement the SetTheory
+// expansion and should be ignored.
+foreach Index = 0-63 in
+ def sv##Index;
+class MaskExpand;
+
+//===----------------------------------------------------------------------===//
+// Available operations
+//===----------------------------------------------------------------------===//
+
+// DAG arguments can either be operations (documented below) or variables.
+// Variables are prefixed with '$'. There are variables for each input argument,
+// with the name $pN, where N starts at zero. So the zero'th argument will be
+// $p0, the first $p1 etc.
+
+// op - Binary or unary operator, depending on the number of arguments. The
+// operator itself is just treated as a raw string and is not checked.
+// example: (op "+", $p0, $p1) -> "__p0 + __p1".
+// (op "-", $p0) -> "-__p0"
+def op;
+// call - Invoke another intrinsic. The input types are type checked and
+// disambiguated. If there is no intrinsic defined that takes
+// the given types (or if there is a type ambiguity) an error is
+// generated at tblgen time. The name of the intrinsic is the raw
+// name as given to the Inst class (not mangled).
+// example: (call "vget_high", $p0) -> "vgetq_high_s16(__p0)"
+// (assuming $p0 has type int16x8_t).
+def call;
+// cast - Perform a cast to a different type. This gets emitted as a static
+// C-style cast. For a pure reinterpret cast (T x = *(T*)&y), use
+// "bitcast".
+//
+// The syntax is (cast MOD* VAL). The last argument is the value to
+// cast, preceded by a sequence of type modifiers. The target type
+// starts off as the type of VAL, and is modified by MOD in sequence.
+// The available modifiers are:
+// - $X - Take the type of parameter/variable X. For example:
+// (cast $p0, $p1) would cast $p1 to the type of $p0.
+// - "R" - The type of the return type.
+// - A typedef string - A NEON or stdint.h type that is then parsed.
+// for example: (cast "uint32x4_t", $p0).
+// - "U" - Make the type unsigned.
+// - "S" - Make the type signed.
+// - "H" - Halve the number of lanes in the type.
+// - "D" - Double the number of lanes in the type.
+// - "8" - Convert type to an equivalent vector of 8-bit signed
+// integers.
+// example: (cast "R", "U", $p0) -> "(uint32x4_t)__p0" (assuming the return
+// value is of type "int32x4_t".
+// (cast $p0, "D", "8", $p1) -> "(int8x16_t)__p1" (assuming __p0
+// has type float64x1_t or any other vector type of 64 bits).
+// (cast "int32_t", $p2) -> "(int32_t)__p2"
+def cast;
+// bitcast - Same as "cast", except a reinterpret-cast is produced:
+// (bitcast "T", $p0) -> "*(T*)&__p0".
+// The VAL argument is saved to a temporary so it can be used
+// as an l-value.
+def bitcast;
+// dup - Take a scalar argument and create a vector by duplicating it into
+// all lanes. The type of the vector is the base type of the intrinsic.
+// example: (dup $p1) -> "(uint32x2_t) {__p1, __p1}" (assuming the base type
+// is uint32x2_t).
+def dup;
+// splat - Take a vector and a lane index, and return a vector of the same type
+// containing repeated instances of the source vector at the lane index.
+// example: (splat $p0, $p1) ->
+// "__builtin_shufflevector(__p0, __p0, __p1, __p1, __p1, __p1)"
+// (assuming __p0 has four elements).
+def splat;
+// save_temp - Create a temporary (local) variable. The variable takes a name
+// based on the zero'th parameter and can be referenced using
+// using that name in subsequent DAGs in the same
+// operation. The scope of a temp is the operation. If a variable
+// with the given name already exists, an error will be given at
+// tblgen time.
+// example: [(save_temp $var, (call "foo", $p0)),
+// (op "+", $var, $p1)] ->
+// "int32x2_t __var = foo(__p0); return __var + __p1;"
+def save_temp;
+// name_replace - Return the name of the current intrinsic with the first
+// argument replaced by the second argument. Raises an error if
+// the first argument does not exist in the intrinsic name.
+// example: (call (name_replace "_high_", "_"), $p0) (to call the non-high
+// version of this intrinsic).
+def name_replace;
+// literal - Create a literal piece of code. The code is treated as a raw
+// string, and must be given a type. The type is a stdint.h or
+// NEON intrinsic type as given to (cast).
+// example: (literal "int32_t", "0")
+def literal;
+// shuffle - Create a vector shuffle. The syntax is (shuffle ARG0, ARG1, MASK).
+// The MASK argument is a set of elements. The elements are generated
+// from the two special defs "mask0" and "mask1". "mask0" expands to
+// the lane indices in sequence for ARG0, and "mask1" expands to
+// the lane indices in sequence for ARG1. They can be used as-is, e.g.
+//
+// (shuffle $p0, $p1, mask0) -> $p0
+// (shuffle $p0, $p1, mask1) -> $p1
+//
+// or, more usefully, they can be manipulated using the SetTheory
+// operators plus some extra operators defined in the NEON emitter.
+// The operators are described below.
+// example: (shuffle $p0, $p1, (add (highhalf mask0), (highhalf mask1))) ->
+// A concatenation of the high halves of the input vectors.
+def shuffle;
+
+// add, interleave, decimate: These set operators are vanilla SetTheory
+// operators and take their normal definition.
+def add;
+def interleave;
+def decimate;
+// rotl - Rotate set left by a number of elements.
+// example: (rotl mask0, 3) -> [3, 4, 5, 6, 0, 1, 2]
+def rotl;
+// rotl - Rotate set right by a number of elements.
+// example: (rotr mask0, 3) -> [4, 5, 6, 0, 1, 2, 3]
+def rotr;
+// highhalf - Take only the high half of the input.
+// example: (highhalf mask0) -> [4, 5, 6, 7] (assuming mask0 had 8 elements)
+def highhalf;
+// highhalf - Take only the low half of the input.
+// example: (lowhalf mask0) -> [0, 1, 2, 3] (assuming mask0 had 8 elements)
+def lowhalf;
+// rev - Perform a variable-width reversal of the elements. The zero'th argument
+// is a width in bits to reverse. The lanes this maps to is determined
+// based on the element width of the underlying type.
+// example: (rev 32, mask0) -> [3, 2, 1, 0, 7, 6, 5, 4] (if 8-bit elements)
+// example: (rev 32, mask0) -> [1, 0, 3, 2] (if 16-bit elements)
+def rev;
+// mask0 - The initial sequence of lanes for shuffle ARG0
+def mask0 : MaskExpand;
+// mask0 - The initial sequence of lanes for shuffle ARG1
+def mask1 : MaskExpand;
+
+def OP_NONE : Operation;
+def OP_UNAVAILABLE : Operation {
+ let Unavailable = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction definitions
+//===----------------------------------------------------------------------===//
+
+// Every intrinsic subclasses "Inst". An intrinsic has a name, a prototype and
+// a sequence of typespecs.
+//
+// The name is the base name of the intrinsic, for example "vget_lane". This is
+// then mangled by the tblgen backend to add type information ("vget_lane_s16").
+//
+// A typespec is a sequence of uppercase characters (modifiers) followed by one
+// lowercase character. A typespec encodes a particular "base type" of the
+// intrinsic.
+//
+// An example typespec is "Qs" - quad-size short - uint16x8_t. The available
+// typespec codes are given below.
+//
+// The string given to an Inst class is a sequence of typespecs. The intrinsic
+// is instantiated for every typespec in the sequence. For example "sdQsQd".
+//
+// The prototype is a string that defines the return type of the intrinsic
+// and the type of each argument. The return type and every argument gets a
+// "modifier" that can change in some way the "base type" of the intrinsic.
+//
+// The modifier 'd' means "default" and does not modify the base type in any
+// way. The available modifiers are given below.
+//
+// Typespecs
+// ---------
+// c: char
+// s: short
+// i: int
+// l: long
+// k: 128-bit long
+// f: float
+// h: half-float
+// d: double
+//
+// Typespec modifiers
+// ------------------
+// S: scalar, only used for function mangling.
+// U: unsigned
+// Q: 128b
+// H: 128b without mangling 'q'
+// P: polynomial
+//
+// Prototype modifiers
+// -------------------
+// prototype: return (arg, arg, ...)
+//
+// v: void
+// t: best-fit integer (int/poly args)
+// x: signed integer (int/float args)
+// u: unsigned integer (int/float args)
+// f: float (int args)
+// F: double (int args)
+// H: half (int args)
+// d: default
+// g: default, ignore 'Q' size modifier.
+// j: default, force 'Q' size modifier.
+// w: double width elements, same num elts
+// n: double width elements, half num elts
+// h: half width elements, double num elts
+// q: half width elements, quad num elts
+// e: half width elements, double num elts, unsigned
+// m: half width elements, same num elts
+// i: constant int
+// l: constant uint64
+// s: scalar of element type
+// z: scalar of half width element type, signed
+// r: scalar of double width element type, signed
+// a: scalar of element type (splat to vector type)
+// b: scalar of unsigned integer/long type (int/float args)
+// $: scalar of signed integer/long type (int/float args)
+// y: scalar of float
+// o: scalar of double
+// k: default elt width, double num elts
+// 2,3,4: array of default vectors
+// B,C,D: array of default elts, force 'Q' size modifier.
+// p: pointer type
+// c: const pointer type
+// 7: vector of 8-bit elements, ignore 'Q' size modifier
+// 8: vector of 8-bit elements, same width as default type
+// 9: vector of 8-bit elements, force 'Q' size modifier
+
+// Every intrinsic subclasses Inst.
+class Inst <string n, string p, string t, Operation o> {
+ string Name = n;
+ string Prototype = p;
+ string Types = t;
+ string ArchGuard = "";
+
+ Operation Operation = o;
+ bit CartesianProductOfTypes = 0;
+ bit BigEndianSafe = 0;
+ bit isShift = 0;
+ bit isScalarShift = 0;
+ bit isScalarNarrowShift = 0;
+ bit isVCVT_N = 0;
+ // For immediate checks: the immediate will be assumed to specify the lane of
+ // a Q register. Only used for intrinsics which end up calling polymorphic
+ // builtins.
+ bit isLaneQ = 0;
+
+ // Certain intrinsics have different names than their representative
+ // instructions. This field allows us to handle this correctly when we
+ // are generating tests.
+ string InstName = "";
+
+ // Certain intrinsics even though they are not a WOpInst or LOpInst,
+ // generate a WOpInst/LOpInst instruction (see below for definition
+ // of a WOpInst/LOpInst). For testing purposes we need to know
+ // this. Ex: vset_lane which outputs vmov instructions.
+ bit isHiddenWInst = 0;
+ bit isHiddenLInst = 0;
+}
+
+// The following instruction classes are implemented via builtins.
+// These declarations are used to generate Builtins.def:
+//
+// SInst: Instruction with signed/unsigned suffix (e.g., "s8", "u8", "p8")
+// IInst: Instruction with generic integer suffix (e.g., "i8")
+// WInst: Instruction with only bit size suffix (e.g., "8")
+class SInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {}
+class IInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {}
+class WInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {}
+
+// The following instruction classes are implemented via operators
+// instead of builtins. As such these declarations are only used for
+// the purpose of generating tests.
+//
+// SOpInst: Instruction with signed/unsigned suffix (e.g., "s8",
+// "u8", "p8").
+// IOpInst: Instruction with generic integer suffix (e.g., "i8").
+// WOpInst: Instruction with bit size only suffix (e.g., "8").
+// LOpInst: Logical instruction with no bit size suffix.
+// NoTestOpInst: Intrinsic that has no corresponding instruction.
+class SOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
+class IOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
+class WOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
+class LOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
+class NoTestOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h
index bb105cb533a41..3d1221a43b146 100644
--- a/include/clang/CodeGen/BackendUtil.h
+++ b/include/clang/CodeGen/BackendUtil.h
@@ -49,6 +49,8 @@ namespace clang {
llvm::Expected<llvm::BitcodeModule>
FindThinLTOModule(llvm::MemoryBufferRef MBRef);
+ llvm::BitcodeModule *
+ FindThinLTOModule(llvm::MutableArrayRef<llvm::BitcodeModule> BMs);
}
#endif
diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h
index d1f05124d5e5e..cf64e9f3eeff8 100644
--- a/include/clang/CodeGen/CGFunctionInfo.h
+++ b/include/clang/CodeGen/CGFunctionInfo.h
@@ -95,6 +95,8 @@ private:
bool SRetAfterThis : 1; // isIndirect()
bool InReg : 1; // isDirect() || isExtend() || isIndirect()
bool CanBeFlattened: 1; // isDirect()
+ bool SignExt : 1; // isExtend()
+ bool SuppressSRet : 1; // isIndirect()
bool canHavePaddingType() const {
return isDirect() || isExtend() || isIndirect() || isExpand();
@@ -110,13 +112,14 @@ private:
}
ABIArgInfo(Kind K)
- : TheKind(K), PaddingInReg(false), InReg(false) {
+ : TheKind(K), PaddingInReg(false), InReg(false), SuppressSRet(false) {
}
public:
ABIArgInfo()
: TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
- TheKind(Direct), PaddingInReg(false), InReg(false) {}
+ TheKind(Direct), PaddingInReg(false), InReg(false),
+ SuppressSRet(false) {}
static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
llvm::Type *Padding = nullptr,
@@ -133,15 +136,38 @@ public:
AI.setInReg(true);
return AI;
}
- static ABIArgInfo getExtend(llvm::Type *T = nullptr) {
+
+ static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T = nullptr) {
+ assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
auto AI = ABIArgInfo(Extend);
AI.setCoerceToType(T);
AI.setPaddingType(nullptr);
AI.setDirectOffset(0);
+ AI.setSignExt(true);
return AI;
}
- static ABIArgInfo getExtendInReg(llvm::Type *T = nullptr) {
- auto AI = getExtend(T);
+
+ static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T = nullptr) {
+ assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
+ auto AI = ABIArgInfo(Extend);
+ AI.setCoerceToType(T);
+ AI.setPaddingType(nullptr);
+ AI.setDirectOffset(0);
+ AI.setSignExt(false);
+ return AI;
+ }
+
+ // ABIArgInfo will record the argument as being extended based on the sign
+ // of its type.
+ static ABIArgInfo getExtend(QualType Ty, llvm::Type *T = nullptr) {
+ assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
+ if (Ty->hasSignedIntegerRepresentation())
+ return getSignExtend(Ty, T);
+ return getZeroExtend(Ty, T);
+ }
+
+ static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T = nullptr) {
+ auto AI = getExtend(Ty, T);
AI.setInReg(true);
return AI;
}
@@ -254,6 +280,15 @@ public:
DirectOffset = Offset;
}
+ bool isSignExt() const {
+ assert(isExtend() && "Invalid kind!");
+ return SignExt;
+ }
+ void setSignExt(bool SExt) {
+ assert(isExtend() && "Invalid kind!");
+ SignExt = SExt;
+ }
+
llvm::Type *getPaddingType() const {
return (canHavePaddingType() ? PaddingType : nullptr);
}
@@ -351,7 +386,7 @@ public:
AllocaFieldIndex = FieldIndex;
}
- /// \brief Return true if this field of an inalloca struct should be returned
+ /// Return true if this field of an inalloca struct should be returned
/// to implement a struct return calling convention.
bool getInAllocaSRet() const {
assert(isInAlloca() && "Invalid kind!");
@@ -373,6 +408,16 @@ public:
CanBeFlattened = Flatten;
}
+ bool getSuppressSRet() const {
+ assert(isIndirect() && "Invalid kind!");
+ return SuppressSRet;
+ }
+
+ void setSuppressSRet(bool Suppress) {
+ assert(isIndirect() && "Invalid kind!");
+ SuppressSRet = Suppress;
+ }
+
void dump() const;
};
@@ -461,7 +506,7 @@ class CGFunctionInfo final
unsigned EffectiveCallingConvention : 8;
/// The clang::CallingConv that this was originally created with.
- unsigned ASTCallingConvention : 7;
+ unsigned ASTCallingConvention : 6;
/// Whether this is an instance method.
unsigned InstanceMethod : 1;
@@ -482,6 +527,9 @@ class CGFunctionInfo final
unsigned HasRegParm : 1;
unsigned RegParm : 3;
+ /// Whether this function has nocf_check attribute.
+ unsigned NoCfCheck : 1;
+
RequiredArgs Required;
/// The struct representing all arguments passed in memory. Only used when
@@ -566,6 +614,9 @@ public:
/// Whether this function no longer saves caller registers.
bool isNoCallerSavedRegs() const { return NoCallerSavedRegs; }
+ /// Whether this function has nocf_check attribute.
+ bool isNoCfCheck() const { return NoCfCheck; }
+
/// getASTCallingConvention() - Return the AST-specified calling
/// convention.
CallingConv getASTCallingConvention() const {
@@ -591,7 +642,7 @@ public:
FunctionType::ExtInfo getExtInfo() const {
return FunctionType::ExtInfo(isNoReturn(), getHasRegParm(), getRegParm(),
getASTCallingConvention(), isReturnsRetained(),
- isNoCallerSavedRegs());
+ isNoCallerSavedRegs(), isNoCfCheck());
}
CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
@@ -609,10 +660,10 @@ public:
return getExtParameterInfos()[argIndex];
}
- /// \brief Return true if this function uses inalloca arguments.
+ /// Return true if this function uses inalloca arguments.
bool usesInAlloca() const { return ArgStruct; }
- /// \brief Get the struct type used to represent all the arguments in memory.
+ /// Get the struct type used to represent all the arguments in memory.
llvm::StructType *getArgStruct() const { return ArgStruct; }
CharUnits getArgStructAlignment() const {
return CharUnits::fromQuantity(ArgStructAlign);
@@ -631,6 +682,7 @@ public:
ID.AddBoolean(NoCallerSavedRegs);
ID.AddBoolean(HasRegParm);
ID.AddInteger(RegParm);
+ ID.AddBoolean(NoCfCheck);
ID.AddInteger(Required.getOpaqueData());
ID.AddBoolean(HasExtParameterInfos);
if (HasExtParameterInfos) {
@@ -657,6 +709,7 @@ public:
ID.AddBoolean(info.getNoCallerSavedRegs());
ID.AddBoolean(info.getHasRegParm());
ID.AddInteger(info.getRegParm());
+ ID.AddBoolean(info.getNoCfCheck());
ID.AddInteger(required.getOpaqueData());
ID.AddBoolean(!paramInfos.empty());
if (!paramInfos.empty()) {
diff --git a/include/clang/CodeGen/ConstantInitBuilder.h b/include/clang/CodeGen/ConstantInitBuilder.h
index 113d86d82c108..f2e78adb8cebb 100644
--- a/include/clang/CodeGen/ConstantInitBuilder.h
+++ b/include/clang/CodeGen/ConstantInitBuilder.h
@@ -266,7 +266,7 @@ public:
/// (2) finishing the entire builder.
///
/// This is useful for emitting certain kinds of structure which
- /// contain some sort of summary field, generaly a count, before any
+ /// contain some sort of summary field, generally a count, before any
/// of the data. By emitting a placeholder first, the structure can
/// be emitted eagerly.
PlaceholderPosition addPlaceholder() {
@@ -295,7 +295,7 @@ public:
slot = value;
}
- /// Produce an address which will eventually point to the the next
+ /// Produce an address which will eventually point to the next
/// position to be filled. This is computed with an indexed
/// getelementptr rather than by computing offsets.
///
diff --git a/include/clang/CodeGen/SwiftCallingConv.h b/include/clang/CodeGen/SwiftCallingConv.h
index 23db43e6739c4..45b3145ed9f1a 100644
--- a/include/clang/CodeGen/SwiftCallingConv.h
+++ b/include/clang/CodeGen/SwiftCallingConv.h
@@ -1,4 +1,4 @@
-//==-- SwiftCallingConv.h - Swift ABI lowering -----------------------------==//
+//==-- SwiftCallingConv.h - Swift ABI lowering ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -116,6 +116,12 @@ private:
void splitVectorEntry(unsigned index);
};
+/// Should an aggregate which expands to the given type sequence
+/// be passed/returned indirectly under swiftcall?
+bool shouldPassIndirectly(CodeGenModule &CGM,
+ ArrayRef<llvm::Type*> types,
+ bool asReturnValue);
+
/// Return the maximum voluntary integer size for the current target.
CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM);
@@ -146,9 +152,15 @@ void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
llvm::VectorType *vectorTy,
llvm::SmallVectorImpl<llvm::Type*> &types);
-/// Should a C++ record type be passed and returned indirectly?
-bool shouldPassCXXRecordIndirectly(CodeGenModule &CGM,
- const CXXRecordDecl *record);
+/// Is the given record type required to be passed and returned indirectly
+/// because of language restrictions?
+///
+/// This considers *only* mandatory indirectness due to language restrictions,
+/// such as C++'s non-trivially-copyable types and Objective-C's __weak
+/// references. A record for which this returns true may still be passed
+/// indirectly for other reasons, such as being too large to fit in a
+/// reasonable number of registers.
+bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record);
/// Classify the rules for how to return a particular type.
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type);
@@ -160,7 +172,7 @@ ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type);
/// private interface for Clang.
void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
-/// Is swifterror lowered to a register by the target ABI.
+/// Is swifterror lowered to a register by the target ABI?
bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM);
} // end namespace swiftcall
diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
index daac9b7b45d1a..1d624450b9d90 100644
--- a/include/clang/Config/config.h.cmake
+++ b/include/clang/Config/config.h.cmake
@@ -11,6 +11,12 @@
/* Default linker to use. */
#define CLANG_DEFAULT_LINKER "${CLANG_DEFAULT_LINKER}"
+/* Default C/ObjC standard to use. */
+#cmakedefine CLANG_DEFAULT_STD_C LangStandard::lang_${CLANG_DEFAULT_STD_C}
+
+/* Default C++/ObjC++ standard to use. */
+#cmakedefine CLANG_DEFAULT_STD_CXX LangStandard::lang_${CLANG_DEFAULT_STD_CXX}
+
/* Default C++ stdlib to use. */
#define CLANG_DEFAULT_CXX_STDLIB "${CLANG_DEFAULT_CXX_STDLIB}"
@@ -35,6 +41,10 @@
/* Directories clang will search for headers */
#define C_INCLUDE_DIRS "${C_INCLUDE_DIRS}"
+/* Directories clang will search for configuration files */
+#cmakedefine CLANG_CONFIG_FILE_SYSTEM_DIR "${CLANG_CONFIG_FILE_SYSTEM_DIR}"
+#cmakedefine CLANG_CONFIG_FILE_USER_DIR "${CLANG_CONFIG_FILE_USER_DIR}"
+
/* Default <path> to all compiler invocations for --sysroot=<path>. */
#define DEFAULT_SYSROOT "${DEFAULT_SYSROOT}"
@@ -62,6 +72,9 @@
/* enable x86 relax relocations by default */
#cmakedefine01 ENABLE_X86_RELAX_RELOCATIONS
+/* Enable the experimental new pass manager by default */
+#cmakedefine01 ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER
+
/* Enable each functionality of modules */
#cmakedefine01 CLANG_ENABLE_ARCMT
#cmakedefine01 CLANG_ENABLE_OBJC_REWRITER
diff --git a/include/clang/CrossTU/CrossTranslationUnit.h b/include/clang/CrossTU/CrossTranslationUnit.h
index f2a1690250090..041f1a8eea590 100644
--- a/include/clang/CrossTU/CrossTranslationUnit.h
+++ b/include/clang/CrossTU/CrossTranslationUnit.h
@@ -62,7 +62,7 @@ private:
int LineNo;
};
-/// \brief This function parses an index file that determines which
+/// This function parses an index file that determines which
/// translation unit contains which definition.
///
/// The index file format is the following:
@@ -75,7 +75,7 @@ parseCrossTUIndex(StringRef IndexPath, StringRef CrossTUDir);
std::string createCrossTUIndexString(const llvm::StringMap<std::string> &Index);
-/// \brief This class is used for tools that requires cross translation
+/// This class is used for tools that requires cross translation
/// unit capability.
///
/// This class can load function definitions from external AST files.
@@ -90,7 +90,7 @@ public:
CrossTranslationUnitContext(CompilerInstance &CI);
~CrossTranslationUnitContext();
- /// \brief This function loads a function definition from an external AST
+ /// This function loads a function definition from an external AST
/// file and merge it into the original AST.
///
/// This method should only be used on functions that have no definitions in
@@ -110,7 +110,7 @@ public:
getCrossTUDefinition(const FunctionDecl *FD, StringRef CrossTUDir,
StringRef IndexName);
- /// \brief This function loads a function definition from an external AST
+ /// This function loads a function definition from an external AST
/// file.
///
/// A function definition with the same declaration will be looked up in the
@@ -126,17 +126,17 @@ public:
StringRef CrossTUDir,
StringRef IndexName);
- /// \brief This function merges a definition from a separate AST Unit into
+ /// This function merges a definition from a separate AST Unit into
/// the current one which was created by the compiler instance that
/// was passed to the constructor.
///
/// \return Returns the resulting definition or an error.
llvm::Expected<const FunctionDecl *> importDefinition(const FunctionDecl *FD);
- /// \brief Get a name to identify a function.
+ /// Get a name to identify a function.
static std::string getLookupName(const NamedDecl *ND);
- /// \brief Emit diagnostics for the user for potential configuration errors.
+ /// Emit diagnostics for the user for potential configuration errors.
void emitCrossTUDiagnostics(const IndexError &IE);
private:
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
index 72456d34a0d95..723fbbed3598a 100644
--- a/include/clang/Driver/Action.h
+++ b/include/clang/Driver/Action.h
@@ -1,4 +1,4 @@
-//===--- Action.h - Abstract compilation steps ------------------*- C++ -*-===//
+//===- Action.h - Abstract compilation steps --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,20 +10,23 @@
#ifndef LLVM_CLANG_DRIVER_ACTION_H
#define LLVM_CLANG_DRIVER_ACTION_H
-#include "clang/Basic/Cuda.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Driver/Types.h"
#include "clang/Driver/Util.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include <string>
namespace llvm {
+namespace opt {
-class StringRef;
+class Arg;
-namespace opt {
- class Arg;
-}
-}
+} // namespace opt
+} // namespace llvm
namespace clang {
namespace driver {
@@ -44,11 +47,11 @@ class ToolChain;
/// actions via MakeAction().
class Action {
public:
- typedef ActionList::size_type size_type;
- typedef ActionList::iterator input_iterator;
- typedef ActionList::const_iterator input_const_iterator;
- typedef llvm::iterator_range<input_iterator> input_range;
- typedef llvm::iterator_range<input_const_iterator> input_const_range;
+ using size_type = ActionList::size_type;
+ using input_iterator = ActionList::iterator;
+ using input_const_iterator = ActionList::const_iterator;
+ using input_range = llvm::iterator_range<input_iterator>;
+ using input_const_range = llvm::iterator_range<input_const_iterator>;
enum ActionClass {
InputClass = 0,
@@ -78,11 +81,14 @@ public:
// to designate the host offloading tool chain.
enum OffloadKind {
OFK_None = 0x00,
+
// The host offloading tool chain.
OFK_Host = 0x01,
+
// The device offloading tool chains - one bit for each programming model.
OFK_Cuda = 0x02,
OFK_OpenMP = 0x04,
+ OFK_HIP = 0x08,
};
static const char *getClassName(ActionClass AC);
@@ -110,8 +116,10 @@ protected:
/// Multiple programming models may be supported simultaneously by the same
/// host.
unsigned ActiveOffloadKindMask = 0u;
+
/// Offloading kind of the device.
OffloadKind OffloadingDeviceKind = OFK_None;
+
/// The Offloading architecture associated with this action.
const char *OffloadingArch = nullptr;
@@ -149,6 +157,7 @@ public:
void setCannotBeCollapsedWithNextDependentAction() {
CanBeCollapsedWithNextDependentAction = false;
}
+
/// Return true if this function can be collapsed with others.
bool isCollapsingWithNextDependentActionLegal() const {
return CanBeCollapsedWithNextDependentAction;
@@ -156,22 +165,26 @@ public:
/// Return a string containing the offload kind of the action.
std::string getOffloadingKindPrefix() const;
+
/// Return a string that can be used as prefix in order to generate unique
/// files for each offloading kind. By default, no prefix is used for
/// non-device kinds, except if \a CreatePrefixForHost is set.
static std::string
GetOffloadingFileNamePrefix(OffloadKind Kind,
- llvm::StringRef NormalizedTriple,
+ StringRef NormalizedTriple,
bool CreatePrefixForHost = false);
+
/// Return a string containing a offload kind name.
static StringRef GetOffloadKindName(OffloadKind Kind);
/// Set the device offload info of this action and propagate it to its
/// dependences.
void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch);
+
/// Append the host offload info of this action and propagate it to its
/// dependences.
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch);
+
/// Set the offload info of this action to be the same as the provided action,
/// and propagate it to its dependences.
void propagateOffloadInfo(const Action *A);
@@ -179,6 +192,7 @@ public:
unsigned getOffloadingHostActiveKinds() const {
return ActiveOffloadKindMask;
}
+
OffloadKind getOffloadingDeviceKind() const { return OffloadingDeviceKind; }
const char *getOffloadingArch() const { return OffloadingArch; }
@@ -196,9 +210,10 @@ public:
};
class InputAction : public Action {
- virtual void anchor();
const llvm::opt::Arg &Input;
+ virtual void anchor();
+
public:
InputAction(const llvm::opt::Arg &Input, types::ID Type);
@@ -211,6 +226,7 @@ public:
class BindArchAction : public Action {
virtual void anchor();
+
/// The architecture to bind, or 0 if the default architecture
/// should be bound.
StringRef ArchName;
@@ -236,9 +252,9 @@ public:
/// toolchain, and offload kind to each action.
class DeviceDependences final {
public:
- typedef SmallVector<const ToolChain *, 3> ToolChainList;
- typedef SmallVector<const char *, 3> BoundArchList;
- typedef SmallVector<OffloadKind, 3> OffloadKindList;
+ using ToolChainList = SmallVector<const ToolChain *, 3>;
+ using BoundArchList = SmallVector<const char *, 3>;
+ using OffloadKindList = SmallVector<OffloadKind, 3>;
private:
// Lists that keep the information for each dependency. All the lists are
@@ -248,10 +264,13 @@ public:
/// The dependence actions.
ActionList DeviceActions;
+
/// The offloading toolchains that should be used with the action.
ToolChainList DeviceToolChains;
+
/// The architectures that should be used with this action.
BoundArchList DeviceBoundArchs;
+
/// The offload kind of each dependence.
OffloadKindList DeviceOffloadKinds;
@@ -262,12 +281,12 @@ public:
OffloadKind OKind);
/// Get each of the individual arrays.
- const ActionList &getActions() const { return DeviceActions; };
- const ToolChainList &getToolChains() const { return DeviceToolChains; };
- const BoundArchList &getBoundArchs() const { return DeviceBoundArchs; };
+ const ActionList &getActions() const { return DeviceActions; }
+ const ToolChainList &getToolChains() const { return DeviceToolChains; }
+ const BoundArchList &getBoundArchs() const { return DeviceBoundArchs; }
const OffloadKindList &getOffloadKinds() const {
return DeviceOffloadKinds;
- };
+ }
};
/// Type used to communicate host actions. It associates bound architecture,
@@ -275,10 +294,13 @@ public:
class HostDependence final {
/// The dependence action.
Action &HostAction;
+
/// The offloading toolchain that should be used with the action.
const ToolChain &HostToolChain;
+
/// The architectures that should be used with this action.
const char *HostBoundArch = nullptr;
+
/// The offload kind of each dependence.
unsigned HostOffloadKinds = 0u;
@@ -286,19 +308,20 @@ public:
HostDependence(Action &A, const ToolChain &TC, const char *BoundArch,
const unsigned OffloadKinds)
: HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch),
- HostOffloadKinds(OffloadKinds){};
+ HostOffloadKinds(OffloadKinds) {}
+
/// Constructor version that obtains the offload kinds from the device
/// dependencies.
HostDependence(Action &A, const ToolChain &TC, const char *BoundArch,
const DeviceDependences &DDeps);
- Action *getAction() const { return &HostAction; };
- const ToolChain *getToolChain() const { return &HostToolChain; };
- const char *getBoundArch() const { return HostBoundArch; };
- unsigned getOffloadKinds() const { return HostOffloadKinds; };
+ Action *getAction() const { return &HostAction; }
+ const ToolChain *getToolChain() const { return &HostToolChain; }
+ const char *getBoundArch() const { return HostBoundArch; }
+ unsigned getOffloadKinds() const { return HostOffloadKinds; }
};
- typedef llvm::function_ref<void(Action *, const ToolChain *, const char *)>
- OffloadActionWorkTy;
+ using OffloadActionWorkTy =
+ llvm::function_ref<void(Action *, const ToolChain *, const char *)>;
private:
/// The host offloading toolchain that should be used with the action.
@@ -349,6 +372,7 @@ public:
class JobAction : public Action {
virtual void anchor();
+
protected:
JobAction(ActionClass Kind, Action *Input, types::ID Type);
JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type);
@@ -362,6 +386,7 @@ public:
class PreprocessJobAction : public JobAction {
void anchor() override;
+
public:
PreprocessJobAction(Action *Input, types::ID OutputType);
@@ -372,6 +397,7 @@ public:
class PrecompileJobAction : public JobAction {
void anchor() override;
+
public:
PrecompileJobAction(Action *Input, types::ID OutputType);
@@ -382,6 +408,7 @@ public:
class AnalyzeJobAction : public JobAction {
void anchor() override;
+
public:
AnalyzeJobAction(Action *Input, types::ID OutputType);
@@ -392,6 +419,7 @@ public:
class MigrateJobAction : public JobAction {
void anchor() override;
+
public:
MigrateJobAction(Action *Input, types::ID OutputType);
@@ -402,6 +430,7 @@ public:
class CompileJobAction : public JobAction {
void anchor() override;
+
public:
CompileJobAction(Action *Input, types::ID OutputType);
@@ -412,6 +441,7 @@ public:
class BackendJobAction : public JobAction {
void anchor() override;
+
public:
BackendJobAction(Action *Input, types::ID OutputType);
@@ -422,6 +452,7 @@ public:
class AssembleJobAction : public JobAction {
void anchor() override;
+
public:
AssembleJobAction(Action *Input, types::ID OutputType);
@@ -432,6 +463,7 @@ public:
class LinkJobAction : public JobAction {
void anchor() override;
+
public:
LinkJobAction(ActionList &Inputs, types::ID Type);
@@ -442,6 +474,7 @@ public:
class LipoJobAction : public JobAction {
void anchor() override;
+
public:
LipoJobAction(ActionList &Inputs, types::ID Type);
@@ -452,6 +485,7 @@ public:
class DsymutilJobAction : public JobAction {
void anchor() override;
+
public:
DsymutilJobAction(ActionList &Inputs, types::ID Type);
@@ -462,8 +496,10 @@ public:
class VerifyJobAction : public JobAction {
void anchor() override;
+
public:
VerifyJobAction(ActionClass Kind, Action *Input, types::ID Type);
+
static bool classof(const Action *A) {
return A->getKind() == VerifyDebugInfoJobClass ||
A->getKind() == VerifyPCHJobClass;
@@ -472,8 +508,10 @@ public:
class VerifyDebugInfoJobAction : public VerifyJobAction {
void anchor() override;
+
public:
VerifyDebugInfoJobAction(Action *Input, types::ID Type);
+
static bool classof(const Action *A) {
return A->getKind() == VerifyDebugInfoJobClass;
}
@@ -481,8 +519,10 @@ public:
class VerifyPCHJobAction : public VerifyJobAction {
void anchor() override;
+
public:
VerifyPCHJobAction(Action *Input, types::ID Type);
+
static bool classof(const Action *A) {
return A->getKind() == VerifyPCHJobClass;
}
@@ -507,18 +547,21 @@ public:
/// Type that provides information about the actions that depend on this
/// unbundling action.
struct DependentActionInfo final {
- /// \brief The tool chain of the dependent action.
+ /// The tool chain of the dependent action.
const ToolChain *DependentToolChain = nullptr;
- /// \brief The bound architecture of the dependent action.
+
+ /// The bound architecture of the dependent action.
StringRef DependentBoundArch;
- /// \brief The offload kind of the dependent action.
+
+ /// The offload kind of the dependent action.
const OffloadKind DependentOffloadKind = OFK_None;
+
DependentActionInfo(const ToolChain *DependentToolChain,
StringRef DependentBoundArch,
const OffloadKind DependentOffloadKind)
: DependentToolChain(DependentToolChain),
DependentBoundArch(DependentBoundArch),
- DependentOffloadKind(DependentOffloadKind){};
+ DependentOffloadKind(DependentOffloadKind) {}
};
private:
@@ -546,7 +589,7 @@ public:
}
};
-} // end namespace driver
-} // end namespace clang
+} // namespace driver
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_DRIVER_ACTION_H
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 7dea88b62cc19..7cb9724a57e19 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -36,6 +36,10 @@ def triple_EQ : Joined<["-"], "triple=">, Alias<triple>;
def mfpmath : Separate<["-"], "mfpmath">,
HelpText<"Which unit to use for fp math">;
+def fpadding_on_unsigned_fixed_point : Flag<["-"], "fpadding-on-unsigned-fixed-point">,
+ HelpText<"Force each unsigned fixed point type to have an extra bit of padding to align their scales with those of signed fixed point types">;
+def fno_padding_on_unsigned_fixed_point : Flag<["-"], "fno-padding-on-unsigned-fixed-point">;
+
//===----------------------------------------------------------------------===//
// Analyzer Options
//===----------------------------------------------------------------------===//
@@ -275,8 +279,6 @@ def split_stacks : Flag<["-"], "split-stacks">,
HelpText<"Try to use a split stack if possible.">;
def mno_zero_initialized_in_bss : Flag<["-"], "mno-zero-initialized-in-bss">,
HelpText<"Do not put zero initialized data in the BSS">;
-def backend_option : Separate<["-"], "backend-option">,
- HelpText<"Additional arguments to forward to LLVM backend (during code gen)">;
def mregparm : Separate<["-"], "mregparm">,
HelpText<"Limit the number of registers available for integer arguments">;
def munwind_tables : Flag<["-"], "munwind-tables">,
@@ -447,6 +449,8 @@ def no_code_completion_ns_level_decls : Flag<["-"], "no-code-completion-ns-level
HelpText<"Do not include declarations inside namespaces (incl. global namespace) in the code-completion results.">;
def code_completion_brief_comments : Flag<["-"], "code-completion-brief-comments">,
HelpText<"Include brief documentation comments in code-completion results.">;
+def code_completion_with_fixits : Flag<["-"], "code-completion-with-fixits">,
+ HelpText<"Include code completion results which require small fix-its.">;
def disable_free : Flag<["-"], "disable-free">,
HelpText<"Disable freeing of memory on exit">;
def discard_value_names : Flag<["-"], "discard-value-names">,
@@ -533,6 +537,8 @@ def ast_dump : Flag<["-"], "ast-dump">,
HelpText<"Build ASTs and then debug dump them">;
def ast_dump_all : Flag<["-"], "ast-dump-all">,
HelpText<"Build ASTs and then debug dump them, forcing deserialization">;
+def templight_dump : Flag<["-"], "templight-dump">,
+ HelpText<"Dump templight information to stdout">;
def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">,
HelpText<"Build ASTs and then debug dump their name lookup tables">;
def ast_view : Flag<["-"], "ast-view">,
@@ -561,6 +567,8 @@ def rewrite_macros : Flag<["-"], "rewrite-macros">,
HelpText<"Expand macros without full preprocessing">;
def migrate : Flag<["-"], "migrate">,
HelpText<"Migrate source code">;
+def compiler_options_dump : Flag<["-"], "compiler-options-dump">,
+ HelpText<"Dump the compiler configuration options">;
}
def emit_llvm_uselists : Flag<["-"], "emit-llvm-uselists">,
@@ -599,13 +607,14 @@ def fixit_to_temp : Flag<["-"], "fixit-to-temporary">,
def foverride_record_layout_EQ : Joined<["-"], "foverride-record-layout=">,
HelpText<"Override record layouts with those in the given file">;
-def find_pch_source_EQ : Joined<["-"], "find-pch-source=">,
- HelpText<"When building a pch, try to find the input file in include "
- "directories, as if it had been included by the argument passed "
- "to this flag.">;
+def pch_through_header_EQ : Joined<["-"], "pch-through-header=">,
+ HelpText<"Stop PCH generation after including this file. When using a PCH, "
+ "skip tokens until after this file is included.">;
def fno_pch_timestamp : Flag<["-"], "fno-pch-timestamp">,
HelpText<"Disable inclusion of timestamp in precompiled headers">;
-
+def building_pch_with_obj : Flag<["-"], "building-pch-with-obj">,
+ HelpText<"This compilation is part of building a PCH with corresponding object file.">;
+
def aligned_alloc_unavailable : Flag<["-"], "faligned-alloc-unavailable">,
HelpText<"Aligned allocation/deallocation functions are unavailable">;
@@ -619,6 +628,8 @@ def version : Flag<["-"], "version">,
HelpText<"Print the compiler version">;
def main_file_name : Separate<["-"], "main-file-name">,
HelpText<"Main file name to use for debug info">;
+def split_dwarf_file : Separate<["-"], "split-dwarf-file">,
+ HelpText<"File name to use for split dwarf debug info output">;
}
@@ -628,8 +639,6 @@ def fexternc_nounwind : Flag<["-"], "fexternc-nounwind">,
HelpText<"Assume all functions with C linkage do not unwind">;
def enable_split_dwarf : Flag<["-"], "enable-split-dwarf">,
HelpText<"Use split dwarf/Fission">;
-def split_dwarf_file : Separate<["-"], "split-dwarf-file">,
- HelpText<"File name to use for split dwarf debug info output">;
def fno_wchar : Flag<["-"], "fno-wchar">,
HelpText<"Disable C++ builtin type wchar_t">;
def fconstant_string_class : Separate<["-"], "fconstant-string-class">,
@@ -645,6 +654,8 @@ def disable_objc_default_synthesize_properties : Flag<["-"], "disable-objc-defau
HelpText<"disable the default synthesis of Objective-C properties">;
def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signature">,
HelpText<"enable extended encoding of block type signature">;
+def function_alignment : Separate<["-"], "function-alignment">,
+ HelpText<"default alignment for functions">;
def pic_level : Separate<["-"], "pic-level">,
HelpText<"Value for __PIC__">;
def pic_is_pie : Flag<["-"], "pic-is-pie">,
@@ -705,8 +716,6 @@ def fobjc_subscripting_legacy_runtime : Flag<["-"], "fobjc-subscripting-legacy-r
HelpText<"Allow Objective-C array and dictionary subscripting in legacy runtime">;
def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">,
HelpText<"Control vtordisp placement on win32 targets">;
-def fno_rtti_data : Flag<["-"], "fno-rtti-data">,
- HelpText<"Control emission of RTTI data">;
def fnative_half_type: Flag<["-"], "fnative-half-type">,
HelpText<"Use the native half type for __fp16 instead of promoting to float">;
def fnative_half_arguments_and_returns : Flag<["-"], "fnative-half-arguments-and-returns">,
diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td
index c1f0a89b5dc8f..78667851ca19c 100644
--- a/include/clang/Driver/CLCompatOptions.td
+++ b/include/clang/Driver/CLCompatOptions.td
@@ -61,6 +61,8 @@ def _SLASH_Brepro_ : CLFlag<"Brepro-">,
def _SLASH_C : CLFlag<"C">,
HelpText<"Don't discard comments when preprocessing">, Alias<C>;
def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias<c>;
+def _SLASH_d1PP : CLFlag<"d1PP">,
+ HelpText<"Retain macro definitions in /E mode">, Alias<dD>;
def _SLASH_d1reportAllClassLayout : CLFlag<"d1reportAllClassLayout">,
HelpText<"Dump record layout information">, Alias<fdump_record_layouts>;
def _SLASH_diagnostics_caret : CLFlag<"diagnostics:caret">,
@@ -164,6 +166,9 @@ def _SLASH_wd4996 : CLFlag<"wd4996">, Alias<W_Joined>,
AliasArgs<["no-deprecated-declarations"]>;
def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">,
Alias<vtordisp_mode_EQ>;
+def _SLASH_X : CLFlag<"X">,
+ HelpText<"Don't add %INCLUDE% to the include search path">,
+ Alias<nostdlibinc>;
def _SLASH_Zc_sizedDealloc : CLFlag<"Zc:sizedDealloc">,
HelpText<"Enable C++14 sized global deallocation functions">,
Alias<fsized_deallocation>;
@@ -235,10 +240,12 @@ def _SLASH_Fi : CLCompileJoined<"Fi">,
def _SLASH_Fo : CLCompileJoined<"Fo">,
HelpText<"Set output object file, or directory (ends in / or \\) (with /c)">,
MetaVarName<"<file or directory>">;
+def _SLASH_Guard : CLJoined<"guard:">,
+ HelpText<"Enable Control Flow Guard with /guard:cf">;
def _SLASH_GX : CLFlag<"GX">,
HelpText<"Enable exception handling">;
def _SLASH_GX_ : CLFlag<"GX-">,
- HelpText<"Enable exception handling">;
+ HelpText<"Disable exception handling">;
def _SLASH_imsvc : CLJoinedOrSeparate<"imsvc">,
HelpText<"Add directory to system include search path, as if part of %INCLUDE%">,
MetaVarName<"<dir>">;
@@ -324,18 +331,20 @@ def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">;
def _SLASH_nologo : CLIgnoredFlag<"nologo">;
def _SLASH_Og : CLIgnoredFlag<"Og">;
def _SLASH_openmp_ : CLIgnoredFlag<"openmp-">;
+def _SLASH_permissive_ : CLIgnoredFlag<"permissive-">;
def _SLASH_RTC : CLIgnoredJoined<"RTC">;
def _SLASH_sdl : CLIgnoredFlag<"sdl">;
def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;
def _SLASH_utf8 : CLIgnoredFlag<"utf-8">,
HelpText<"Set source and runtime encoding to UTF-8 (default)">;
def _SLASH_w : CLIgnoredJoined<"w">;
+def _SLASH_Zc___cplusplus : CLIgnoredFlag<"Zc:__cplusplus">;
def _SLASH_Zc_auto : CLIgnoredFlag<"Zc:auto">;
def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">;
def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">;
def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">;
-def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">;
+def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
def _SLASH_Zm : CLIgnoredJoined<"Zm">;
def _SLASH_Zo : CLIgnoredFlag<"Zo">;
def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">;
@@ -344,6 +353,8 @@ def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">;
// Unsupported:
def _SLASH_AI : CLJoined<"AI">;
+def _SLASH_Bt : CLFlag<"Bt">;
+def _SLASH_Bt_plus : CLFlag<"Bt+">;
def _SLASH_clr : CLJoined<"clr">;
def _SLASH_doc : CLJoined<"doc">;
def _SLASH_FA_joined : CLJoined<"FA">;
@@ -364,7 +375,6 @@ def _SLASH_GL_ : CLFlag<"GL-">;
def _SLASH_Gm : CLFlag<"Gm">;
def _SLASH_Gm_ : CLFlag<"Gm-">;
def _SLASH_GT : CLFlag<"GT">;
-def _SLASH_Guard : CLJoined<"guard:">;
def _SLASH_GZ : CLFlag<"GZ">;
def _SLASH_H : CLFlag<"H">;
def _SLASH_homeparams : CLFlag<"homeparams">;
@@ -382,7 +392,6 @@ def _SLASH_u : CLFlag<"u">;
def _SLASH_V : CLFlag<"V">;
def _SLASH_WL : CLFlag<"WL">;
def _SLASH_Wp64 : CLFlag<"Wp64">;
-def _SLASH_X : CLFlag<"X">;
def _SLASH_Yd : CLFlag<"Yd">;
def _SLASH_Yl : CLJoined<"Yl">;
def _SLASH_Za : CLFlag<"Za">;
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
index 89c0def6c57a0..20eb07f6de8bd 100644
--- a/include/clang/Driver/Compilation.h
+++ b/include/clang/Driver/Compilation.h
@@ -1,4 +1,4 @@
-//===--- Compilation.h - Compilation Task Data Structure --------*- C++ -*-===//
+//===- Compilation.h - Compilation Task Data Structure ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,24 +10,36 @@
#ifndef LLVM_CLANG_DRIVER_COMPILATION_H
#define LLVM_CLANG_DRIVER_COMPILATION_H
+#include "clang/Basic/LLVM.h"
#include "clang/Driver/Action.h"
#include "clang/Driver/Job.h"
#include "clang/Driver/Util.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/Option.h"
+#include <cassert>
+#include <iterator>
#include <map>
+#include <memory>
+#include <utility>
+#include <vector>
namespace llvm {
namespace opt {
- class DerivedArgList;
- class InputArgList;
-}
-}
+
+class DerivedArgList;
+class InputArgList;
+
+} // namespace opt
+} // namespace llvm
namespace clang {
namespace driver {
- class Driver;
- class JobList;
- class ToolChain;
+
+class Driver;
+class ToolChain;
/// Compilation - A set of tasks to perform for a single driver
/// invocation.
@@ -40,7 +52,7 @@ class Compilation {
/// A mask of all the programming models the host has to support in the
/// current compilation.
- unsigned ActiveOffloadMask;
+ unsigned ActiveOffloadMask = 0;
/// Array with the toolchains of offloading host and devices in the order they
/// were requested by the user. We are preserving that order in case the code
@@ -73,6 +85,11 @@ class Compilation {
const ToolChain *TC = nullptr;
StringRef BoundArch;
Action::OffloadKind DeviceOffloadKind = Action::OFK_None;
+
+ TCArgsKey(const ToolChain *TC, StringRef BoundArch,
+ Action::OffloadKind DeviceOffloadKind)
+ : TC(TC), BoundArch(BoundArch), DeviceOffloadKind(DeviceOffloadKind) {}
+
bool operator<(const TCArgsKey &K) const {
if (TC < K.TC)
return true;
@@ -83,9 +100,6 @@ class Compilation {
return true;
return false;
}
- TCArgsKey(const ToolChain *TC, StringRef BoundArch,
- Action::OffloadKind DeviceOffloadKind)
- : TC(TC), BoundArch(BoundArch), DeviceOffloadKind(DeviceOffloadKind) {}
};
std::map<TCArgsKey, llvm::opt::DerivedArgList *> TCArgs;
@@ -103,11 +117,14 @@ class Compilation {
std::vector<Optional<StringRef>> Redirects;
/// Whether we're compiling for diagnostic purposes.
- bool ForDiagnostics;
+ bool ForDiagnostics = false;
/// Whether an error during the parsing of the input args.
bool ContainsError;
+ /// Whether to keep temporary files regardless of -save-temps.
+ bool ForceKeepTempFiles = false;
+
public:
Compilation(const Driver &D, const ToolChain &DefaultToolChain,
llvm::opt::InputArgList *Args,
@@ -123,12 +140,12 @@ public:
}
/// Iterator that visits device toolchains of a given kind.
- typedef const std::multimap<Action::OffloadKind,
- const ToolChain *>::const_iterator
- const_offload_toolchains_iterator;
- typedef std::pair<const_offload_toolchains_iterator,
- const_offload_toolchains_iterator>
- const_offload_toolchains_range;
+ using const_offload_toolchains_iterator =
+ const std::multimap<Action::OffloadKind,
+ const ToolChain *>::const_iterator;
+ using const_offload_toolchains_range =
+ std::pair<const_offload_toolchains_iterator,
+ const_offload_toolchains_iterator>;
template <Action::OffloadKind Kind>
const_offload_toolchains_range getOffloadToolChains() const {
@@ -289,7 +306,7 @@ public:
void Redirect(ArrayRef<Optional<StringRef>> Redirects);
};
-} // end namespace driver
-} // end namespace clang
+} // namespace driver
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_DRIVER_COMPILATION_H
diff --git a/include/clang/Driver/Distro.h b/include/clang/Driver/Distro.h
index 4ab4e2ae99370..7b34a0925603e 100644
--- a/include/clang/Driver/Distro.h
+++ b/include/clang/Driver/Distro.h
@@ -61,6 +61,7 @@ public:
UbuntuZesty,
UbuntuArtful,
UbuntuBionic,
+ UbuntuCosmic,
UnknownDistro
};
@@ -114,7 +115,7 @@ public:
}
bool IsUbuntu() const {
- return DistroVal >= UbuntuHardy && DistroVal <= UbuntuBionic;
+ return DistroVal >= UbuntuHardy && DistroVal <= UbuntuCosmic;
}
bool IsAlpineLinux() const {
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index a3662872a9531..017248c3690f1 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -19,6 +19,8 @@
#include "clang/Driver/Util.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/StringSaver.h"
#include <list>
#include <map>
@@ -26,14 +28,6 @@
namespace llvm {
class Triple;
-
-namespace opt {
- class Arg;
- class ArgList;
- class DerivedArgList;
- class InputArgList;
- class OptTable;
-}
}
namespace clang {
@@ -138,6 +132,12 @@ public:
/// The path to the compiler resource directory.
std::string ResourceDir;
+ /// System directory for config files.
+ std::string SystemConfigDir;
+
+ /// User directory for config files.
+ std::string UserConfigDir;
+
/// A prefix directory used to emulate a limited subset of GCC's '-Bprefix'
/// functionality.
/// FIXME: This type of customization should be removed in favor of the
@@ -202,12 +202,27 @@ public:
unsigned CCGenDiagnostics : 1;
private:
- /// Default target triple.
- std::string DefaultTargetTriple;
+ /// Raw target triple.
+ std::string TargetTriple;
/// Name to use when invoking gcc/g++.
std::string CCCGenericGCCName;
+ /// Name of configuration file if used.
+ std::string ConfigFile;
+
+ /// Allocator for string saver.
+ llvm::BumpPtrAllocator Alloc;
+
+ /// Object that stores strings read from configuration file.
+ llvm::StringSaver Saver;
+
+ /// Arguments originated from configuration file.
+ std::unique_ptr<llvm::opt::InputArgList> CfgOptions;
+
+ /// Arguments originated from command line.
+ std::unique_ptr<llvm::opt::InputArgList> CLOptions;
+
/// Whether to check that input files exist when constructing compilation
/// jobs.
unsigned CheckInputsExist : 1;
@@ -228,7 +243,7 @@ private:
std::list<std::string> TempFiles;
std::list<std::string> ResultFiles;
- /// \brief Cache of all the ToolChains in use by the driver.
+ /// Cache of all the ToolChains in use by the driver.
///
/// This maps from the string representation of a triple to a ToolChain
/// created targeting that triple. The driver owns all the ToolChain objects
@@ -252,7 +267,7 @@ private:
void generatePrefixedToolNames(StringRef Tool, const ToolChain &TC,
SmallVectorImpl<std::string> &Names) const;
- /// \brief Find the appropriate .crash diagonostic file for the child crash
+ /// Find the appropriate .crash diagonostic file for the child crash
/// under this driver and copy it out to a temporary destination with the
/// other reproducer related files (.sh, .cache, etc). If not found, suggest a
/// directory for the user to look at.
@@ -267,7 +282,7 @@ private:
SmallString<128> &CrashDiagDir);
public:
- Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple,
+ Driver(StringRef ClangExecutable, StringRef TargetTriple,
DiagnosticsEngine &Diags,
IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);
@@ -277,6 +292,8 @@ public:
/// Name to use when invoking gcc/g++.
const std::string &getCCCGenericGCCName() const { return CCCGenericGCCName; }
+ const std::string &getConfigFile() const { return ConfigFile; }
+
const llvm::opt::OptTable &getOpts() const { return *Opts; }
const DiagnosticsEngine &getDiags() const { return Diags; }
@@ -292,12 +309,14 @@ public:
const std::string &getTitle() { return DriverTitle; }
void setTitle(std::string Value) { DriverTitle = std::move(Value); }
- /// \brief Get the path to the main clang executable.
+ std::string getTargetTriple() const { return TargetTriple; }
+
+ /// Get the path to the main clang executable.
const char *getClangProgramPath() const {
return ClangExecutable.c_str();
}
- /// \brief Get the path to where the clang executable was installed.
+ /// Get the path to where the clang executable was installed.
const char *getInstalledDir() const {
if (!InstalledDir.empty())
return InstalledDir.c_str();
@@ -388,11 +407,19 @@ public:
int ExecuteCompilation(Compilation &C,
SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands);
- /// generateCompilationDiagnostics - Generate diagnostics information
+ /// Contains the files in the compilation diagnostic report generated by
+ /// generateCompilationDiagnostics.
+ struct CompilationDiagnosticReport {
+ llvm::SmallVector<std::string, 4> TemporaryFiles;
+ };
+
+ /// generateCompilationDiagnostics - Generate diagnostics information
/// including preprocessed source file(s).
- ///
- void generateCompilationDiagnostics(Compilation &C,
- const Command &FailingCommand);
+ ///
+ void generateCompilationDiagnostics(
+ Compilation &C, const Command &FailingCommand,
+ StringRef AdditionalInformation = "",
+ CompilationDiagnosticReport *GeneratedReport = nullptr);
/// @}
/// @name Helper Methods
@@ -425,9 +452,9 @@ public:
// FIXME: This should be in CompilationInfo.
std::string GetProgramPath(StringRef Name, const ToolChain &TC) const;
- /// handleAutocompletions - Handle --autocomplete by searching and printing
+ /// HandleAutocompletions - Handle --autocomplete by searching and printing
/// possible flags, descriptions, and its arguments.
- void handleAutocompletions(StringRef PassedFlags) const;
+ void HandleAutocompletions(StringRef PassedFlags) const;
/// HandleImmediateArgs - Handle any arguments which should be
/// treated before building actions or binding tools.
@@ -439,8 +466,10 @@ public:
/// ConstructAction - Construct the appropriate action to do for
/// \p Phase on the \p Input, taking in to account arguments
/// like -fsyntax-only or --analyze.
- Action *ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args,
- phases::ID Phase, Action *Input) const;
+ Action *ConstructPhaseAction(
+ Compilation &C, const llvm::opt::ArgList &Args, phases::ID Phase,
+ Action *Input,
+ Action::OffloadKind TargetDeviceOffloadKind = Action::OFK_None) const;
/// BuildJobsForAction - Construct the jobs to perform for the action \p A and
/// return an InputInfo for the result of running \p A. Will only construct
@@ -493,6 +522,18 @@ public:
LTOKind getLTOMode() const { return LTOMode; }
private:
+
+ /// Tries to load options from configuration file.
+ ///
+ /// \returns true if error occurred.
+ bool loadConfigFile();
+
+ /// Read options from the specified file.
+ ///
+ /// \param [in] FileName File to read.
+ /// \returns true, if error occurred while reading.
+ bool readConfigFile(StringRef FileName);
+
/// Set the driver mode (cl, gcc, etc) from an option string of the form
/// --driver-mode=<mode>.
void setDriverModeFromOption(StringRef Opt);
@@ -501,7 +542,7 @@ private:
/// compilation based on which -f(no-)?lto(=.*)? option occurs last.
void setLTOMode(const llvm::opt::ArgList &Args);
- /// \brief Retrieves a ToolChain for a particular \p Target triple.
+ /// Retrieves a ToolChain for a particular \p Target triple.
///
/// Will cache ToolChains for the life of the driver object, and create them
/// on-demand.
@@ -510,7 +551,7 @@ private:
/// @}
- /// \brief Get bitmasks for which option flags to include and exclude based on
+ /// Get bitmasks for which option flags to include and exclude based on
/// the driver mode.
std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks() const;
@@ -543,6 +584,8 @@ public:
/// no extra characters remaining at the end.
static bool GetReleaseVersion(StringRef Str,
MutableArrayRef<unsigned> Digits);
+ /// Compute the default -fmodule-cache-path.
+ static void getDefaultModuleCachePath(SmallVectorImpl<char> &Result);
};
/// \return True if the last defined optimization level is -Ofast.
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index b74b3b4b35e1b..47d9e992ba503 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -1,4 +1,4 @@
-//===--- Job.h - Commands to Execute ----------------------------*- C++ -*-===//
+//===- Job.h - Commands to Execute ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,21 +12,22 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Option/Option.h"
#include <memory>
-
-namespace llvm {
- class raw_ostream;
-}
+#include <string>
+#include <utility>
+#include <vector>
namespace clang {
namespace driver {
+
class Action;
-class Command;
-class Tool;
class InputInfo;
+class Tool;
// Re-export this as clang::driver::ArgStringList.
using llvm::opt::ArgStringList;
@@ -60,7 +61,7 @@ class Command {
/// Response file name, if this command is set to use one, or nullptr
/// otherwise
- const char *ResponseFile;
+ const char *ResponseFile = nullptr;
/// The input file list in case we need to emit a file list instead of a
/// proper response file
@@ -92,7 +93,7 @@ public:
// FIXME: This really shouldn't be copyable, but is currently copied in some
// error handling in Driver::generateCompilationDiagnostics.
Command(const Command &) = default;
- virtual ~Command() {}
+ virtual ~Command() = default;
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
CrashReportInfo *CrashInfo = nullptr) const;
@@ -115,7 +116,7 @@ public:
InputFileList = std::move(List);
}
- /// \brief Sets the environment to be used by the new process.
+ /// Sets the environment to be used by the new process.
/// \param NewEnvironment An array of environment variables.
/// \remark If the environment remains unset, then the environment
/// from the parent process will be used.
@@ -165,10 +166,10 @@ public:
/// JobList - A sequence of jobs to perform.
class JobList {
public:
- typedef SmallVector<std::unique_ptr<Command>, 4> list_type;
- typedef list_type::size_type size_type;
- typedef llvm::pointee_iterator<list_type::iterator> iterator;
- typedef llvm::pointee_iterator<list_type::const_iterator> const_iterator;
+ using list_type = SmallVector<std::unique_ptr<Command>, 4>;
+ using size_type = list_type::size_type;
+ using iterator = llvm::pointee_iterator<list_type::iterator>;
+ using const_iterator = llvm::pointee_iterator<list_type::const_iterator>;
private:
list_type Jobs;
@@ -193,7 +194,7 @@ public:
const_iterator end() const { return Jobs.end(); }
};
-} // end namespace driver
-} // end namespace clang
+} // namespace driver
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_DRIVER_JOB_H
diff --git a/include/clang/Driver/Multilib.h b/include/clang/Driver/Multilib.h
index 36d2493b1afca..132d981854fcb 100644
--- a/include/clang/Driver/Multilib.h
+++ b/include/clang/Driver/Multilib.h
@@ -1,4 +1,4 @@
-//===--- Multilib.h ---------------------------------------------*- C++ -*-===//
+//===- Multilib.h -----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,10 +11,14 @@
#define LLVM_CLANG_DRIVER_MULTILIB_H
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Option/Option.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include <cassert>
#include <functional>
#include <string>
+#include <utility>
#include <vector>
namespace clang {
@@ -24,7 +28,7 @@ namespace driver {
/// by a command line flag
class Multilib {
public:
- typedef std::vector<std::string> flags_list;
+ using flags_list = std::vector<std::string>;
private:
std::string GCCSuffix;
@@ -33,40 +37,43 @@ private:
flags_list Flags;
public:
- Multilib(StringRef GCCSuffix = "", StringRef OSSuffix = "",
- StringRef IncludeSuffix = "");
+ Multilib(StringRef GCCSuffix = {}, StringRef OSSuffix = {},
+ StringRef IncludeSuffix = {});
- /// \brief Get the detected GCC installation path suffix for the multi-arch
+ /// Get the detected GCC installation path suffix for the multi-arch
/// target variant. Always starts with a '/', unless empty
const std::string &gccSuffix() const {
assert(GCCSuffix.empty() ||
(StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
return GCCSuffix;
}
+
/// Set the GCC installation path suffix.
Multilib &gccSuffix(StringRef S);
- /// \brief Get the detected os path suffix for the multi-arch
+ /// Get the detected os path suffix for the multi-arch
/// target variant. Always starts with a '/', unless empty
const std::string &osSuffix() const {
assert(OSSuffix.empty() ||
(StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1));
return OSSuffix;
}
+
/// Set the os path suffix.
Multilib &osSuffix(StringRef S);
- /// \brief Get the include directory suffix. Always starts with a '/', unless
+ /// Get the include directory suffix. Always starts with a '/', unless
/// empty
const std::string &includeSuffix() const {
assert(IncludeSuffix.empty() ||
(StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1));
return IncludeSuffix;
}
+
/// Set the include directory suffix
Multilib &includeSuffix(StringRef S);
- /// \brief Get the flags that indicate or contraindicate this multilib's use
+ /// Get the flags that indicate or contraindicate this multilib's use
/// All elements begin with either '+' or '-'
const flags_list &flags() const { return Flags; }
flags_list &flags() { return Flags; }
@@ -85,7 +92,7 @@ public:
}
LLVM_DUMP_METHOD void dump() const;
- /// \brief print summary of the Multilib
+ /// print summary of the Multilib
void print(raw_ostream &OS) const;
/// Check whether any of the 'against' flags contradict the 'for' flags.
@@ -102,14 +109,12 @@ raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
class MultilibSet {
public:
- typedef std::vector<Multilib> multilib_list;
- typedef multilib_list::iterator iterator;
- typedef multilib_list::const_iterator const_iterator;
-
- typedef std::function<std::vector<std::string>(const Multilib &M)>
- IncludeDirsFunc;
-
- typedef llvm::function_ref<bool(const Multilib &)> FilterCallback;
+ using multilib_list = std::vector<Multilib>;
+ using iterator = multilib_list::iterator;
+ using const_iterator = multilib_list::const_iterator;
+ using IncludeDirsFunc =
+ std::function<std::vector<std::string>(const Multilib &M)>;
+ using FilterCallback = llvm::function_ref<bool(const Multilib &)>;
private:
multilib_list Multilibs;
@@ -117,7 +122,7 @@ private:
IncludeDirsFunc FilePathsCallback;
public:
- MultilibSet() {}
+ MultilibSet() = default;
/// Add an optional Multilib segment
MultilibSet &Maybe(const Multilib &M);
@@ -135,6 +140,7 @@ public:
/// Filter out some subset of the Multilibs using a user defined callback
MultilibSet &FilterOut(FilterCallback F);
+
/// Filter out those Multilibs whose gccSuffix matches the given expression
MultilibSet &FilterOut(const char *Regex);
@@ -144,7 +150,7 @@ public:
/// Union this set of multilibs with another
void combineWith(const MultilibSet &MS);
- /// Remove all of thie multilibs from the set
+ /// Remove all of the multilibs from the set
void clear() { Multilibs.clear(); }
iterator begin() { return Multilibs.begin(); }
@@ -165,12 +171,14 @@ public:
IncludeCallback = std::move(F);
return *this;
}
+
const IncludeDirsFunc &includeDirsCallback() const { return IncludeCallback; }
MultilibSet &setFilePathsCallback(IncludeDirsFunc F) {
FilePathsCallback = std::move(F);
return *this;
}
+
const IncludeDirsFunc &filePathsCallback() const { return FilePathsCallback; }
private:
@@ -182,8 +190,8 @@ private:
};
raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
-}
-}
-#endif
+} // namespace driver
+} // namespace clang
+#endif // LLVM_CLANG_DRIVER_MULTILIB_H
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 09efd7b0af63f..2470638bec66b 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -143,14 +143,18 @@ def m_hexagon_Features_Group : OptionGroup<"<hexagon features group>">,
// These are explicitly handled.
def m_hexagon_Features_HVX_Group : OptionGroup<"<hexagon features group>">,
Group<m_Group>, DocName<"Hexagon">;
+def m_mips_Features_Group : OptionGroup<"<mips features group>">,
+ Group<m_Group>, DocName<"MIPS">;
def m_ppc_Features_Group : OptionGroup<"<ppc features group>">,
Group<m_Group>, DocName<"PowerPC">;
def m_wasm_Features_Group : OptionGroup<"<wasm features group>">,
Group<m_Group>, DocName<"WebAssembly">;
def m_x86_Features_Group : OptionGroup<"<x86 features group>">,
Group<m_Group>, Flags<[CoreOption]>, DocName<"X86">;
+def m_riscv_Features_Group : OptionGroup<"<riscv features group>">,
+ Group<m_Group>, DocName<"RISCV">;
-def m_libc_Group : OptionGroup<"<m libc group>">, Group<m_Group>,
+def m_libc_Group : OptionGroup<"<m libc group>">, Group<m_mips_Features_Group>,
Flags<[HelpHidden]>;
def O_Group : OptionGroup<"<O group>">, Group<CompileOnly_Group>,
@@ -396,7 +400,12 @@ def O_flag : Flag<["-"], "O">, Flags<[CC1Option]>, Alias<O>, AliasArgs<["2"]>;
def Ofast : Joined<["-"], "Ofast">, Group<O_Group>, Flags<[CC1Option]>;
def P : Flag<["-"], "P">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
HelpText<"Disable linemarker output in -E mode">;
-def Qn : Flag<["-"], "Qn">, IgnoredGCCCompat;
+def Qy : Flag<["-"], "Qy">, Flags<[CC1Option]>,
+ HelpText<"Emit metadata containing compiler name and version">;
+def Qn : Flag<["-"], "Qn">, Flags<[CC1Option]>,
+ HelpText<"Do not emit metadata containing compiler name and version">;
+def : Flag<["-"], "fident">, Group<f_Group>, Alias<Qy>, Flags<[CC1Option]>;
+def : Flag<["-"], "fno-ident">, Group<f_Group>, Alias<Qn>, Flags<[CC1Option]>;
def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Flags<[DriverOption, CoreOption]>,
HelpText<"Don't emit warning for unused driver arguments">;
def Q : Flag<["-"], "Q">, IgnoredGCCCompat;
@@ -418,9 +427,9 @@ def S : Flag<["-"], "S">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>,
MetaVarName<"<addr>">, HelpText<"Set starting address of BSS to <addr>">;
def Tdata : JoinedOrSeparate<["-"], "Tdata">, Group<T_Group>,
- MetaVarName<"<addr>">, HelpText<"Set starting address of BSS to <addr>">;
+ MetaVarName<"<addr>">, HelpText<"Set starting address of DATA to <addr>">;
def Ttext : JoinedOrSeparate<["-"], "Ttext">, Group<T_Group>,
- MetaVarName<"<addr>">, HelpText<"Set starting address of BSS to <addr>">;
+ MetaVarName<"<addr>">, HelpText<"Set starting address of TEXT to <addr>">;
def T : JoinedOrSeparate<["-"], "T">, Group<T_Group>,
MetaVarName<"<script>">, HelpText<"Specify <script> as linker script">;
def U : JoinedOrSeparate<["-"], "U">, Group<Preprocessor_Group>,
@@ -466,7 +475,8 @@ def Xcuda_ptxas : Separate<["-"], "Xcuda-ptxas">,
def Xopenmp_target : Separate<["-"], "Xopenmp-target">,
HelpText<"Pass <arg> to the target offloading toolchain.">, MetaVarName<"<arg>">;
def Xopenmp_target_EQ : JoinedAndSeparate<["-"], "Xopenmp-target=">,
- HelpText<"Pass <arg> to the specified target offloading toolchain. The triple that identifies the toolchain must be provided after the equals sign.">, MetaVarName<"<arg>">;
+ HelpText<"Pass <arg> to the target offloading toolchain identified by <triple>.">,
+ MetaVarName<"<triple> <arg>">;
def z : Separate<["-"], "z">, Flags<[LinkerInput, RenderAsInput]>,
HelpText<"Pass -z <arg> to the linker">, MetaVarName<"<arg>">,
Group<Link_Group>;
@@ -492,6 +502,8 @@ def bind__at__load : Flag<["-"], "bind_at_load">;
def bundle__loader : Separate<["-"], "bundle_loader">;
def bundle : Flag<["-"], "bundle">;
def b : JoinedOrSeparate<["-"], "b">, Flags<[Unsupported]>;
+def cfguard : Flag<["-"], "cfguard">, Flags<[CC1Option]>,
+ HelpText<"Emit tables required for Windows Control Flow Guard.">;
def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>, Flags<[CC1Option]>,
HelpText<"OpenCL only. This option disables all optimizations. By default optimizations are enabled.">;
def cl_strict_aliasing : Flag<["-"], "cl-strict-aliasing">, Group<opencl_Group>, Flags<[CC1Option]>,
@@ -511,14 +523,22 @@ def cl_mad_enable : Flag<["-"], "cl-mad-enable">, Group<opencl_Group>, Flags<[CC
def cl_no_signed_zeros : Flag<["-"], "cl-no-signed-zeros">, Group<opencl_Group>, Flags<[CC1Option]>,
HelpText<"OpenCL only. Allow use of less precise no signed zeros computations in the generated binary.">;
def cl_std_EQ : Joined<["-"], "cl-std=">, Group<opencl_Group>, Flags<[CC1Option]>,
- HelpText<"OpenCL language standard to compile for.">, Values<"cl,CL,cl1.1,CL1.1,cl1.2,CL1.2,cl2.0,CL2.0">;
+ HelpText<"OpenCL language standard to compile for.">, Values<"cl,CL,cl1.1,CL1.1,cl1.2,CL1.2,cl2.0,CL2.0,c++">;
def cl_denorms_are_zero : Flag<["-"], "cl-denorms-are-zero">, Group<opencl_Group>, Flags<[CC1Option]>,
HelpText<"OpenCL only. Allow denormals to be flushed to zero.">;
def cl_fp32_correctly_rounded_divide_sqrt : Flag<["-"], "cl-fp32-correctly-rounded-divide-sqrt">, Group<opencl_Group>, Flags<[CC1Option]>,
HelpText<"OpenCL only. Specify that single precision floating-point divide and sqrt used in the program source are correctly rounded.">;
+def cl_uniform_work_group_size : Flag<["-"], "cl-uniform-work-group-size">, Group<opencl_Group>, Flags<[CC1Option]>,
+ HelpText<"OpenCL only. Defines that the global work-size be a multiple of the work-group size specified to clEnqueueNDRangeKernel">;
def client__name : JoinedOrSeparate<["-"], "client_name">;
def combine : Flag<["-", "--"], "combine">, Flags<[DriverOption, Unsupported]>;
def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">;
+def config : Separate<["--"], "config">, Flags<[DriverOption]>,
+ HelpText<"Specifies configuration file">;
+def config_system_dir_EQ : Joined<["--"], "config-system-dir=">, Flags<[DriverOption, HelpHidden]>,
+ HelpText<"System directory for configuration files">;
+def config_user_dir_EQ : Joined<["--"], "config-user-dir=">, Flags<[DriverOption, HelpHidden]>,
+ HelpText<"User directory for configuration files">;
def coverage : Flag<["-", "--"], "coverage">, Flags<[CoreOption]>;
def cpp_precomp : Flag<["-"], "cpp-precomp">, Group<clang_ignored_f_Group>;
def current__version : JoinedOrSeparate<["-"], "current_version">;
@@ -535,8 +555,14 @@ def cuda_host_only : Flag<["--"], "cuda-host-only">,
def cuda_compile_host_device : Flag<["--"], "cuda-compile-host-device">,
HelpText<"Compile CUDA code for both host and device (default). Has no "
"effect on non-CUDA compilations.">;
+def cuda_include_ptx_EQ : Joined<["--"], "cuda-include-ptx=">, Flags<[DriverOption]>,
+ HelpText<"Include PTX for the follwing GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">;
+def no_cuda_include_ptx_EQ : Joined<["--"], "no-cuda-include-ptx=">, Flags<[DriverOption]>,
+ HelpText<"Do not include PTX for the follwing GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">;
def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption]>,
HelpText<"CUDA GPU architecture (e.g. sm_35). May be specified more than once.">;
+def hip_link : Flag<["--"], "hip-link">,
+ HelpText<"Link clang-offload-bundler bundles for HIP">;
def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[DriverOption]>,
HelpText<"Remove GPU architecture (e.g. sm_35) from the list of GPUs to compile for. "
"'all' resets the list to its default value.">;
@@ -548,6 +574,8 @@ def no_cuda_version_check : Flag<["--"], "no-cuda-version-check">,
def no_cuda_noopt_device_debug : Flag<["--"], "no-cuda-noopt-device-debug">;
def cuda_path_EQ : Joined<["--"], "cuda-path=">, Group<i_Group>,
HelpText<"CUDA installation path">;
+def cuda_path_ignore_env : Flag<["--"], "cuda-path-ignore-env">, Group<i_Group>,
+ HelpText<"Ignore environment variables to detect CUDA installation">;
def ptxas_path_EQ : Joined<["--"], "ptxas-path=">, Group<i_Group>,
HelpText<"Path to ptxas (used for compiling CUDA code)">;
def fcuda_flush_denormals_to_zero : Flag<["-"], "fcuda-flush-denormals-to-zero">,
@@ -556,6 +584,18 @@ def fno_cuda_flush_denormals_to_zero : Flag<["-"], "fno-cuda-flush-denormals-to-
def fcuda_approx_transcendentals : Flag<["-"], "fcuda-approx-transcendentals">,
Flags<[CC1Option]>, HelpText<"Use approximate transcendental functions">;
def fno_cuda_approx_transcendentals : Flag<["-"], "fno-cuda-approx-transcendentals">;
+def fcuda_rdc : Flag<["-"], "fcuda-rdc">, Flags<[CC1Option]>,
+ HelpText<"Generate relocatable device code, also known as separate compilation mode.">;
+def fno_cuda_rdc : Flag<["-"], "fno-cuda-rdc">;
+def fcuda_short_ptr : Flag<["-"], "fcuda-short-ptr">, Flags<[CC1Option]>,
+ HelpText<"Use 32-bit pointers for accessing const/local/shared address spaces.">;
+def fno_cuda_short_ptr : Flag<["-"], "fno-cuda-short-ptr">;
+def hip_device_lib_path_EQ : Joined<["--"], "hip-device-lib-path=">, Group<Link_Group>,
+ HelpText<"HIP device library path">;
+def hip_device_lib_EQ : Joined<["--"], "hip-device-lib=">, Group<Link_Group>,
+ HelpText<"HIP device library">;
+def fhip_dump_offload_linker_script : Flag<["-"], "fhip-dump-offload-linker-script">,
+ Group<f_Group>, Flags<[NoArgumentUnused, HelpHidden]>;
def dA : Flag<["-"], "dA">, Group<d_Group>;
def dD : Flag<["-"], "dD">, Group<d_Group>, Flags<[CC1Option]>,
HelpText<"Print macro definitions in -E mode in addition to normal output">;
@@ -591,6 +631,9 @@ def fno_PIC : Flag<["-"], "fno-PIC">, Group<f_Group>;
def fPIE : Flag<["-"], "fPIE">, Group<f_Group>;
def fno_PIE : Flag<["-"], "fno-PIE">, Group<f_Group>;
def faccess_control : Flag<["-"], "faccess-control">, Group<f_Group>;
+def falign_functions : Flag<["-"], "falign-functions">, Group<f_Group>;
+def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<f_Group>;
+def fno_align_functions: Flag<["-"], "fno-align-functions">, Group<f_Group>;
def fallow_unsupported : Flag<["-"], "fallow-unsupported">, Group<f_Group>;
def fapple_kext : Flag<["-"], "fapple-kext">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use Apple's kernel extensions ABI">;
@@ -687,10 +730,10 @@ def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">,
Group<f_Group>, Flags<[CoreOption]>,
HelpText<"Use instrumentation data for profile-guided optimization">;
def fcoverage_mapping : Flag<["-"], "fcoverage-mapping">,
- Group<f_Group>, Flags<[CC1Option]>,
+ Group<f_Group>, Flags<[CC1Option, CoreOption]>,
HelpText<"Generate coverage mapping to enable code coverage analysis">;
def fno_coverage_mapping : Flag<["-"], "fno-coverage-mapping">,
- Group<f_Group>, Flags<[DriverOption]>,
+ Group<f_Group>, Flags<[DriverOption, CoreOption]>,
HelpText<"Disable code coverage analysis">;
def fprofile_generate : Flag<["-"], "fprofile-generate">,
Group<f_Group>, Flags<[DriverOption]>,
@@ -715,12 +758,16 @@ def fno_profile_instr_use : Flag<["-"], "fno-profile-instr-use">,
def fno_profile_use : Flag<["-"], "fno-profile-use">,
Alias<fno_profile_instr_use>;
-def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[CC1Option]>,
+def faddrsig : Flag<["-"], "faddrsig">, Group<f_Group>, Flags<[CoreOption, CC1Option]>,
+ HelpText<"Emit an address-significance table">;
+def fno_addrsig : Flag<["-"], "fno-addrsig">, Group<f_Group>, Flags<[CoreOption]>,
+ HelpText<"Don't emit an address-significance table">;
+def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[CoreOption, CC1Option]>,
HelpText<"Enable the 'blocks' language feature">;
def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>;
def fborland_extensions : Flag<["-"], "fborland-extensions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Accept non-standard constructs supported by the Borland compiler">;
-def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>;
+def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>, Flags<[CoreOption]>;
def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group<f_Group>,
Flags<[DriverOption]>, HelpText<"Load the clang builtins module map file.">;
def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>;
@@ -741,6 +788,12 @@ def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Gr
def fparse_all_comments : Flag<["-"], "fparse-all-comments">, Group<f_clang_Group>, Flags<[CC1Option]>;
def fcommon : Flag<["-"], "fcommon">, Group<f_Group>;
def fcompile_resource_EQ : Joined<["-"], "fcompile-resource=">, Group<f_Group>;
+def fcomplete_member_pointers : Flag<["-"], "fcomplete-member-pointers">, Group<f_clang_Group>,
+ Flags<[CoreOption, CC1Option]>,
+ HelpText<"Require member pointer base types to be complete if they would be significant under the Microsoft ABI">;
+def fno_complete_member_pointers : Flag<["-"], "fno-complete-member-pointers">, Group<f_clang_Group>,
+ Flags<[CoreOption]>,
+ HelpText<"Do not require member pointer base types to be complete if they would be significant under the Microsoft ABI">;
def fconstant_cfstrings : Flag<["-"], "fconstant-cfstrings">, Group<f_Group>;
def fconstant_string_class_EQ : Joined<["-"], "fconstant-string-class=">, Group<f_Group>;
def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>;
@@ -749,6 +802,7 @@ def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">
Group<f_Group>;
def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>,
HelpText<"Disable auto-generation of preprocessed source files and a script for reproduction during a clang crash">;
+def fcrash_diagnostics_dir : Joined<["-"], "fcrash-diagnostics-dir=">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>;
def fcreate_profile : Flag<["-"], "fcreate-profile">, Group<f_Group>;
def fcxx_exceptions: Flag<["-"], "fcxx-exceptions">, Group<f_Group>,
HelpText<"Enable C++ exceptions">, Flags<[CC1Option]>;
@@ -780,6 +834,10 @@ def fdiagnostics_show_template_tree : Flag<["-"], "fdiagnostics-show-template-tr
HelpText<"Print a template comparison tree for differing templates">;
def fdeclspec : Flag<["-"], "fdeclspec">, Group<f_clang_Group>,
HelpText<"Allow __declspec as a keyword">, Flags<[CC1Option]>;
+def fdiscard_value_names : Flag<["-"], "fdiscard-value-names">, Group<f_clang_Group>,
+ HelpText<"Discard value names in LLVM IR">, Flags<[DriverOption]>;
+def fno_discard_value_names : Flag<["-"], "fno-discard-value-names">, Group<f_clang_Group>,
+ HelpText<"Do not discard value names in LLVM IR">, Flags<[DriverOption]>;
def fdollars_in_identifiers : Flag<["-"], "fdollars-in-identifiers">, Group<f_Group>,
HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>;
def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group<clang_ignored_f_Group>;
@@ -795,7 +853,7 @@ def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>, Flags<[CC1
HelpText<"Emit all declarations, even if unused">;
def femulated_tls : Flag<["-"], "femulated-tls">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use emutls functions to access thread_local variables">;
-def fno_emulated_tls : Flag<["-"], "fno-emulated-tls">, Group<f_Group>;
+def fno_emulated_tls : Flag<["-"], "fno-emulated-tls">, Group<f_Group>, Flags<[CC1Option]>;
def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>;
def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>, Flags<[CoreOption]>;
def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>,
@@ -829,6 +887,17 @@ def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>;
def fjump_tables : Flag<["-"], "fjump-tables">, Group<f_Group>;
def fno_jump_tables : Flag<["-"], "fno-jump-tables">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Do not use jump tables for lowering switches">;
+def fforce_enable_int128 : Flag<["-"], "fforce-enable-int128">,
+ Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Enable support for int128_t type">;
+def fno_force_enable_int128 : Flag<["-"], "fno-force-enable-int128">,
+ Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Disable support for int128_t type">;
+
+def ffixed_point : Flag<["-"], "ffixed-point">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Enable fixed point types">;
+def fno_fixed_point : Flag<["-"], "fno-fixed-point">, Group<f_Group>,
+ HelpText<"Disable fixed point types">;
// Begin sanitizer flags. These should all be core options exposed in all driver
// modes.
@@ -881,6 +950,14 @@ def fno_sanitize_address_use_after_scope : Flag<["-"], "fno-sanitize-address-use
Group<f_clang_Group>,
Flags<[CoreOption, DriverOption]>,
HelpText<"Disable use-after-scope detection in AddressSanitizer">;
+def fsanitize_address_poison_class_member_array_new_cookie
+ : Flag<[ "-" ], "fsanitize-address-poison-class-member-array-new-cookie">,
+ Group<f_clang_Group>,
+ HelpText<"Enable poisoning array cookies when using class member operator new[] in AddressSanitizer">;
+def fno_sanitize_address_poison_class_member_array_new_cookie
+ : Flag<[ "-" ], "fno-sanitize-address-poison-class-member-array-new-cookie">,
+ Group<f_clang_Group>,
+ HelpText<"Disable poisoning array cookies when using class member operator new[] in AddressSanitizer">;
def fsanitize_address_globals_dead_stripping : Flag<["-"], "fsanitize-address-globals-dead-stripping">,
Group<f_clang_Group>,
HelpText<"Enable linker dead stripping of globals in AddressSanitizer">;
@@ -985,6 +1062,13 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Form fused FP ops (e.g. FMAs): fast (everywhere)"
" | on (according to FP_CONTRACT pragma, default) | off (never fuse)">, Values<"fast,on,off">;
+def fstrict_float_cast_overflow : Flag<["-"],
+ "fstrict-float-cast-overflow">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Assume that overflowing float-to-int casts are undefined (default)">;
+def fno_strict_float_cast_overflow : Flag<["-"],
+ "fno-strict-float-cast-overflow">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Relax language rules and try to match the behavior of the target's native float-to-int conversion instructions">;
+
def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>;
def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>;
@@ -996,6 +1080,13 @@ def frewrite_imports : Flag<["-"], "frewrite-imports">, Group<f_Group>,
Flags<[CC1Option]>;
def fno_rewrite_imports : Flag<["-"], "fno-rewrite-imports">, Group<f_Group>;
+def fdelete_null_pointer_checks : Flag<["-"],
+ "fdelete-null-pointer-checks">, Group<f_Group>,
+ HelpText<"Treat usage of null pointers as undefined behavior.">;
+def fno_delete_null_pointer_checks : Flag<["-"],
+ "fno-delete-null-pointer-checks">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Do not treat usage of null pointers as undefined behavior.">;
+
def frewrite_map_file : Separate<["-"], "frewrite-map-file">,
Group<f_Group>,
Flags<[ DriverOption, CC1Option ]>;
@@ -1025,6 +1116,8 @@ def finline_functions : Flag<["-"], "finline-functions">, Group<f_clang_Group>,
def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Inline functions which are (explicitly or implicitly) marked inline">;
def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
+def fexperimental_isel : Flag<["-"], "fexperimental-isel">, Group<f_clang_Group>,
+ HelpText<"Enables the experimental global instruction selector">;
def fexperimental_new_pass_manager : Flag<["-"], "fexperimental-new-pass-manager">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Enables an experimental new pass manager in LLVM.">;
@@ -1036,6 +1129,11 @@ def finstrument_functions_after_inlining : Flag<["-"], "finstrument-functions-af
HelpText<"Like -finstrument-functions, but insert the calls after inlining">;
def finstrument_function_entry_bare : Flag<["-"], "finstrument-function-entry-bare">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Instrument function entry only, after inlining, without arguments to the instrumentation call">;
+def fcf_protection_EQ : Joined<["-"], "fcf-protection=">, Flags<[CoreOption, CC1Option]>, Group<f_Group>,
+ HelpText<"Instrument control-flow architecture protection. Options: return, branch, full, none.">, Values<"return,branch,full,none">;
+def fcf_protection : Flag<["-"], "fcf-protection">, Group<f_Group>, Flags<[CoreOption, CC1Option]>,
+ Alias<fcf_protection_EQ>, AliasArgs<["full"]>,
+ HelpText<"Enable cf-protection in 'full' mode">;
def fxray_instrument : Flag<["-"], "fxray-instrument">, Group<f_Group>,
Flags<[CC1Option]>,
@@ -1054,11 +1152,19 @@ def fxray_instruction_threshold_ :
def fxray_always_instrument :
JoinedOrSeparate<["-"], "fxray-always-instrument=">,
Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Filename defining the whitelist for imbuing the 'always instrument' XRay attribute.">;
+ HelpText<"DEPRECATED: Filename defining the whitelist for imbuing the 'always instrument' XRay attribute.">;
def fxray_never_instrument :
JoinedOrSeparate<["-"], "fxray-never-instrument=">,
Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.">;
+ HelpText<"DEPRECATED: Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.">;
+def fxray_attr_list :
+ JoinedOrSeparate<["-"], "fxray-attr-list=">,
+ Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Filename defining the list of functions/types for imbuing XRay attributes.">;
+def fxray_modes :
+ JoinedOrSeparate<["-"], "fxray-modes=">,
+ Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"List of modes to link in by default into XRay instrumented binaries.">;
def fxray_always_emit_customevents : Flag<["-"], "fxray-always-emit-customevents">, Group<f_Group>,
Flags<[CC1Option]>,
@@ -1066,9 +1172,26 @@ def fxray_always_emit_customevents : Flag<["-"], "fxray-always-emit-customevents
def fnoxray_always_emit_customevents : Flag<["-"], "fno-xray-always-emit-customevents">, Group<f_Group>,
Flags<[CC1Option]>;
+def fxray_always_emit_typedevents : Flag<["-"], "fxray-always-emit-typedevents">, Group<f_Group>,
+ Flags<[CC1Option]>,
+ HelpText<"Determine whether to always emit __xray_typedevent(...) calls even if the function it appears in is not always instrumented.">;
+def fnoxray_always_emit_typedevents : Flag<["-"], "fno-xray-always-emit-typedevents">, Group<f_Group>,
+ Flags<[CC1Option]>;
+
+def fxray_link_deps : Flag<["-"], "fxray-link-deps">, Group<f_Group>,
+ Flags<[CC1Option]>,
+ HelpText<"Tells clang to add the link dependencies for XRay.">;
+def fnoxray_link_deps : Flag<["-"], "fnoxray-link-deps">, Group<f_Group>,
+ Flags<[CC1Option]>;
+
+def fxray_instrumentation_bundle :
+ JoinedOrSeparate<["-"], "fxray-instrumentation-bundle=">,
+ Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Select which XRay instrumentation points to emit. Options: all, none, function, custom. Default is 'all'.">;
+
def ffine_grained_bitfield_accesses : Flag<["-"],
"ffine-grained-bitfield-accesses">, Group<f_clang_Group>, Flags<[CC1Option]>,
- HelpText<"Use separate accesses for bitfields with legal widths and alignments.">;
+ HelpText<"Use separate accesses for consecutive bitfield runs with legal widths and alignments.">;
def fno_fine_grained_bitfield_accesses : Flag<["-"],
"fno-fine-grained-bitfield-accesses">, Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Use large-integer access for consecutive bitfield runs.">;
@@ -1092,7 +1215,8 @@ def fthinlto_index_EQ : Joined<["-"], "fthinlto-index=">,
HelpText<"Perform ThinLTO importing using provided function summary index">;
def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">,
Group<f_Group>, Flags<[DriverOption, CoreOption]>;
-def fmerge_all_constants : Flag<["-"], "fmerge-all-constants">, Group<f_Group>;
+def fmerge_all_constants : Flag<["-"], "fmerge-all-constants">, Group<f_Group>,
+ Flags<[CC1Option, CoreOption]>, HelpText<"Allow merging of constants">;
def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group<f_Group>;
def fms_extensions : Flag<["-"], "fms-extensions">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">;
@@ -1146,6 +1270,8 @@ def fmodules_disable_diagnostic_validation : Flag<["-"], "fmodules-disable-diagn
def fmodules_validate_system_headers : Flag<["-"], "fmodules-validate-system-headers">,
Group<i_Group>, Flags<[CC1Option]>,
HelpText<"Validate the system headers that a module depends on when loading the module">;
+def fno_modules_validate_system_headers : Flag<["-"], "fno-modules-validate-system-headers">,
+ Group<i_Group>, Flags<[DriverOption]>;
def fmodules : Flag <["-"], "fmodules">, Group<f_Group>,
Flags<[DriverOption, CC1Option]>,
HelpText<"Enable the 'modules' language feature">;
@@ -1194,11 +1320,11 @@ def fno_asynchronous_unwind_tables : Flag<["-"], "fno-asynchronous-unwind-tables
def fno_assume_sane_operator_new : Flag<["-"], "fno-assume-sane-operator-new">, Group<f_Group>,
HelpText<"Don't assume that C++'s global operator new can't alias any pointer">,
Flags<[CC1Option]>;
-def fno_blocks : Flag<["-"], "fno-blocks">, Group<f_Group>;
+def fno_blocks : Flag<["-"], "fno-blocks">, Group<f_Group>, Flags<[CoreOption]>;
def fno_borland_extensions : Flag<["-"], "fno-borland-extensions">, Group<f_Group>;
-def fno_builtin : Flag<["-"], "fno-builtin">, Group<f_Group>, Flags<[CC1Option]>,
+def fno_builtin : Flag<["-"], "fno-builtin">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
HelpText<"Disable implicit builtin knowledge of functions">;
-def fno_builtin_ : Joined<["-"], "fno-builtin-">, Group<f_Group>, Flags<[CC1Option]>,
+def fno_builtin_ : Joined<["-"], "fno-builtin-">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
HelpText<"Disable implicit builtin knowledge of a specific function">;
def fno_caret_diagnostics : Flag<["-"], "fno-caret-diagnostics">, Group<f_Group>,
Flags<[CC1Option]>;
@@ -1220,6 +1346,10 @@ def fno_diagnostics_show_hotness : Flag<["-"], "fno-diagnostics-show-hotness">,
def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group<f_Group>;
def fno_diagnostics_show_note_include_stack : Flag<["-"], "fno-diagnostics-show-note-include-stack">,
Flags<[CC1Option]>, Group<f_Group>;
+def fdigraphs : Flag<["-"], "fdigraphs">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Enable alternative token representations '<:', ':>', '<%', '%>', '%:', '%:%:' (default)">;
+def fno_digraphs : Flag<["-"], "fno-digraphs">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Disallow alternative token representations '<:', ':>', '<%', '%>', '%:', '%:%:'">;
def fno_declspec : Flag<["-"], "fno-declspec">, Group<f_clang_Group>,
HelpText<"Disallow __declspec as a keyword">, Flags<[CC1Option]>;
def fno_dollars_in_identifiers : Flag<["-"], "fno-dollars-in-identifiers">, Group<f_Group>,
@@ -1231,6 +1361,8 @@ def fno_exceptions : Flag<["-"], "fno-exceptions">, Group<f_Group>;
def fno_gnu_keywords : Flag<["-"], "fno-gnu-keywords">, Group<f_Group>, Flags<[CC1Option]>;
def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>;
def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>, Flags<[CC1Option]>;
+def fno_experimental_isel : Flag<["-"], "fno-experimental-isel">, Group<f_clang_Group>,
+ HelpText<"Disables the experimental global instruction selector">;
def fno_experimental_new_pass_manager : Flag<["-"], "fno-experimental-new-pass-manager">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Disables an experimental new pass manager in LLVM.">;
@@ -1239,7 +1371,7 @@ def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>, Flags<[CC1Option]>,
def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>,
HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">, Flags<[CC1Option]>;
def fno_merge_all_constants : Flag<["-"], "fno-merge-all-constants">, Group<f_Group>,
- Flags<[CC1Option]>, HelpText<"Disallow merging of constants">;
+ HelpText<"Disallow merging of constants">;
def fno_modules : Flag <["-"], "fno-modules">, Group<f_Group>,
Flags<[DriverOption]>;
def fno_implicit_module_maps : Flag <["-"], "fno-implicit-module-maps">, Group<f_Group>,
@@ -1272,6 +1404,8 @@ def fno_operator_names : Flag<["-"], "fno-operator-names">, Group<f_Group>,
def fno_pascal_strings : Flag<["-"], "fno-pascal-strings">, Group<f_Group>;
def fno_rtti : Flag<["-"], "fno-rtti">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Disable generation of rtti information">;
+def fno_rtti_data : Flag<["-"], "fno-rtti-data">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Control emission of RTTI data">;
def fno_short_enums : Flag<["-"], "fno-short-enums">, Group<f_Group>;
def fno_show_column : Flag<["-"], "fno-show-column">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Do not include column number on diagnostics">;
@@ -1295,6 +1429,8 @@ def fno_threadsafe_statics : Flag<["-"], "fno-threadsafe-statics">, Group<f_Grou
Flags<[CC1Option]>, HelpText<"Do not emit code to make initialization of local statics thread safe">;
def fno_use_cxa_atexit : Flag<["-"], "fno-use-cxa-atexit">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Don't use __cxa_atexit for calling destructors">;
+def fno_register_global_dtors_with_atexit : Flag<["-"], "fno-register-global-dtors-with-atexit">, Group<f_Group>,
+ HelpText<"Don't use atexit or __cxa_atexit to register global destructors">;
def fno_use_init_array : Flag<["-"], "fno-use-init-array">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Don't use .init_array instead of .ctors">;
def fno_unit_at_a_time : Flag<["-"], "fno-unit-at-a-time">, Group<f_Group>;
@@ -1361,22 +1497,34 @@ def fno_objc_nonfragile_abi : Flag<["-"], "fno-objc-nonfragile-abi">, Group<f_Gr
def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>;
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
-def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
+def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
+ HelpText<"Parse OpenMP pragmas and generate parallel code.">;
def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>, Flags<[NoArgumentUnused]>;
def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>;
-def fopenmp_use_tls : Flag<["-"], "fopenmp-use-tls">, Group<f_Group>, Flags<[NoArgumentUnused]>;
-def fnoopenmp_use_tls : Flag<["-"], "fnoopenmp-use-tls">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
+def fopenmp_use_tls : Flag<["-"], "fopenmp-use-tls">, Group<f_Group>,
+ Flags<[NoArgumentUnused, HelpHidden]>;
+def fnoopenmp_use_tls : Flag<["-"], "fnoopenmp-use-tls">, Group<f_Group>,
+ Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
def fopenmp_targets_EQ : CommaJoined<["-"], "fopenmp-targets=">, Flags<[DriverOption, CC1Option]>,
HelpText<"Specify comma-separated list of triples OpenMP offloading targets to be supported">;
-def fopenmp_dump_offload_linker_script : Flag<["-"], "fopenmp-dump-offload-linker-script">, Group<f_Group>,
- Flags<[NoArgumentUnused]>;
-def fopenmp_relocatable_target : Flag<["-"], "fopenmp-relocatable-target">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
- HelpText<"OpenMP target code is compiled as relocatable using the -c flag. For OpenMP targets the code is relocatable by default.">;
-def fnoopenmp_relocatable_target : Flag<["-"], "fnoopenmp-relocatable-target">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
- HelpText<"Do not compile OpenMP target code as relocatable.">;
+def fopenmp_dump_offload_linker_script : Flag<["-"], "fopenmp-dump-offload-linker-script">,
+ Group<f_Group>, Flags<[NoArgumentUnused, HelpHidden]>;
+def fopenmp_relocatable_target : Flag<["-"], "fopenmp-relocatable-target">,
+ Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+def fnoopenmp_relocatable_target : Flag<["-"], "fnoopenmp-relocatable-target">,
+ Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+def fopenmp_simd : Flag<["-"], "fopenmp-simd">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
+ HelpText<"Emit OpenMP code only for SIMD-based constructs.">;
+def fno_openmp_simd : Flag<["-"], "fno-openmp-simd">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
+def fopenmp_cuda_mode : Flag<["-"], "fopenmp-cuda-mode">, Group<f_Group>,
+ Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+def fno_openmp_cuda_mode : Flag<["-"], "fno-openmp-cuda-mode">, Group<f_Group>,
+ Flags<[NoArgumentUnused, HelpHidden]>;
def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
+def fno_escaping_block_tail_calls : Flag<["-"], "fno-escaping-block-tail-calls">, Group<f_Group>, Flags<[CC1Option]>;
+def fescaping_block_tail_calls : Flag<["-"], "fescaping-block-tail-calls">, Group<f_Group>;
def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;
def force__flat__namespace : Flag<["-"], "force_flat_namespace">;
def force__load : Separate<["-"], "force_load">;
@@ -1421,6 +1569,10 @@ def frtti : Flag<["-"], "frtti">, Group<f_Group>;
def : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>;
def fshort_enums : Flag<["-"], "fshort-enums">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Allocate to an enum type only as many bytes as it needs for the declared range of possible values">;
+def fchar8__t : Flag<["-"], "fchar8_t">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Enable C++ builtin type char8_t">;
+def fno_char8__t : Flag<["-"], "fno-char8_t">, Group<f_Group>,
+ HelpText<"Disable C++ builtin type char8_t">;
def fshort_wchar : Flag<["-"], "fshort-wchar">, Group<f_Group>,
HelpText<"Force wchar_t to be a short unsigned int">;
def fno_short_wchar : Flag<["-"], "fno-short-wchar">, Group<f_Group>,
@@ -1533,6 +1685,8 @@ def funsigned_char : Flag<["-"], "funsigned-char">, Group<f_Group>;
def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">;
def funwind_tables : Flag<["-"], "funwind-tables">, Group<f_Group>;
def fuse_cxa_atexit : Flag<["-"], "fuse-cxa-atexit">, Group<f_Group>;
+def fregister_global_dtors_with_atexit : Flag<["-"], "fregister-global-dtors-with-atexit">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Use atexit or __cxa_atexit to register global destructors">;
def fuse_init_array : Flag<["-"], "fuse-init-array">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use .init_array instead of .ctors">;
def fno_var_tracking : Flag<["-"], "fno-var-tracking">, Group<clang_ignored_f_Group>;
@@ -1540,7 +1694,7 @@ def fverbose_asm : Flag<["-"], "fverbose-asm">, Group<f_Group>;
def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group<f_Group>,
HelpText<"Set the default symbol visibility for all global declarations">, Values<"hidden,default">;
def fvisibility_inlines_hidden : Flag<["-"], "fvisibility-inlines-hidden">, Group<f_Group>,
- HelpText<"Give inline C++ member functions default visibility by default">,
+ HelpText<"Give inline C++ member functions hidden visibility by default">,
Flags<[CC1Option]>;
def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group<f_Group>,
HelpText<"Give global types 'default' visibility and global functions and "
@@ -1550,6 +1704,11 @@ def fwhole_program_vtables : Flag<["-"], "fwhole-program-vtables">, Group<f_Grou
HelpText<"Enables whole-program vtable optimization. Requires -flto">;
def fno_whole_program_vtables : Flag<["-"], "fno-whole-program-vtables">, Group<f_Group>,
Flags<[CoreOption]>;
+def fforce_emit_vtables : Flag<["-"], "fforce-emit-vtables">, Group<f_Group>,
+ Flags<[CC1Option]>,
+ HelpText<"Emits more virtual tables to improve devirtualization">;
+def fno_force_emit_vtables : Flag<["-"], "fno-force-emit-vtables">, Group<f_Group>,
+ Flags<[CoreOption]>;
def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Treat signed integer overflow as two's complement">;
def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>, Flags<[CC1Option]>,
@@ -1564,6 +1723,10 @@ def fdata_sections : Flag <["-"], "fdata-sections">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Place each data in its own section (ELF Only)">;
def fno_data_sections : Flag <["-"], "fno-data-sections">, Group<f_Group>,
Flags<[CC1Option]>;
+def fstack_size_section : Flag<["-"], "fstack-size-section">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Emit section containing metadata on function stack sizes">;
+def fno_stack_size_section : Flag<["-"], "fno-stack-size-section">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Don't emit section containing metadata on function stack sizes">;
def funique_section_names : Flag <["-"], "funique-section-names">,
Group<f_Group>, Flags<[CC1Option]>,
@@ -1589,11 +1752,12 @@ def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>,
def fno_debug_types_section: Flag<["-"], "fno-debug-types-section">, Group<f_Group>,
Flags<[CC1Option]>;
def fsplit_dwarf_inlining: Flag <["-"], "fsplit-dwarf-inlining">, Group<f_Group>,
- Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">;
+ Flags<[CC1Option]>, HelpText<"Provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF">;
def fno_split_dwarf_inlining: Flag<["-"], "fno-split-dwarf-inlining">, Group<f_Group>,
Flags<[CC1Option]>;
def fdebug_prefix_map_EQ
- : Joined<["-"], "fdebug-prefix-map=">, Group<f_Group>, Flags<[CC1Option]>,
+ : Joined<["-"], "fdebug-prefix-map=">, Group<f_Group>,
+ Flags<[CC1Option,CC1AsOption]>,
HelpText<"remap file source paths in debug info">;
def g_Flag : Flag<["-"], "g">, Group<g_Group>,
HelpText<"Generate source-level debug information">;
@@ -1642,6 +1806,7 @@ def gcolumn_info : Flag<["-"], "gcolumn-info">, Group<g_flags_Group>, Flags<[Cor
def gno_column_info : Flag<["-"], "gno-column-info">, Group<g_flags_Group>, Flags<[CoreOption]>;
def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>;
def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>, Flags<[CC1Option]>;
+def gno_gnu_pubnames : Flag<["-"], "gno-gnu-pubnames">, Group<g_flags_Group>, Flags<[CC1Option]>;
def gdwarf_aranges : Flag<["-"], "gdwarf-aranges">, Group<g_flags_Group>;
def gmodules : Flag <["-"], "gmodules">, Group<gN_Group>,
HelpText<"Generate debug info with external references to clang modules"
@@ -1650,6 +1815,11 @@ def gz : Flag<["-"], "gz">, Group<g_flags_Group>,
HelpText<"DWARF debug sections compression type">;
def gz_EQ : Joined<["-"], "gz=">, Group<g_flags_Group>,
HelpText<"DWARF debug sections compression type">;
+def gembed_source : Flag<["-"], "gembed-source">, Group<g_flags_Group>, Flags<[CC1Option]>,
+ HelpText<"Embed source text in DWARF debug sections">;
+def gno_embed_source : Flag<["-"], "gno-embed-source">, Group<g_flags_Group>,
+ Flags<[DriverOption]>,
+ HelpText<"Restore the default behavior of not embedding source text in DWARF debug sections">;
def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">;
def help : Flag<["-", "--"], "help">, Flags<[CC1Option,CC1AsOption]>,
HelpText<"Display available options">;
@@ -1700,7 +1870,7 @@ def iwithsysroot : JoinedOrSeparate<["-"], "iwithsysroot">, Group<clang_i_Group>
Flags<[CC1Option]>;
def ivfsoverlay : JoinedOrSeparate<["-"], "ivfsoverlay">, Group<clang_i_Group>, Flags<[CC1Option]>,
HelpText<"Overlay the virtual filesystem described by file over the real file system">;
-def i : Joined<["-"], "i">, Group<i_Group>;
+def imultilib : Separate<["-"], "imultilib">, Group<gfortran_Group>;
def keep__private__externs : Flag<["-"], "keep_private_externs">;
def l : JoinedOrSeparate<["-"], "l">, Flags<[LinkerInput, RenderJoined]>,
Group<Link_Group>;
@@ -1787,6 +1957,10 @@ def mmacos_version_min_EQ : Joined<["-"], "mmacos-version-min=">,
Group<m_Group>, Alias<mmacosx_version_min_EQ>;
def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>, Flags<[CC1Option]>,
HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard">;
+def moutline : Flag<["-"], "moutline">, Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Enable function outlining (AArch64 only)">;
+def mno_outline : Flag<["-"], "mno-outline">, Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Disable function outlining (AArch64 only)">;
def mno_ms_bitfields : Flag<["-"], "mno-ms-bitfields">, Group<m_Group>,
HelpText<"Do not set the default structure layout to be compatible with the Microsoft compiler standard">;
def mstackrealign : Flag<["-"], "mstackrealign">, Group<m_Group>, Flags<[CC1Option]>,
@@ -1795,6 +1969,10 @@ def mstack_alignment : Joined<["-"], "mstack-alignment=">, Group<m_Group>, Flags
HelpText<"Set the stack alignment">;
def mstack_probe_size : Joined<["-"], "mstack-probe-size=">, Group<m_Group>, Flags<[CC1Option]>,
HelpText<"Set the stack probe size">;
+def mstack_arg_probe : Flag<["-"], "mstack-arg-probe">, Group<m_Group>,
+ HelpText<"Enable stack probes">;
+def mno_stack_arg_probe : Flag<["-"], "mno-stack-arg-probe">, Group<m_Group>, Flags<[CC1Option]>,
+ HelpText<"Disable stack probes which are enabled by default">;
def mthread_model : Separate<["-"], "mthread-model">, Group<m_Group>, Flags<[CC1Option]>,
HelpText<"The thread model to use, e.g. posix, single (posix by default)">, Values<"posix,single">;
def meabi : Separate<["-"], "meabi">, Group<m_Group>, Flags<[CC1Option]>,
@@ -1811,6 +1989,11 @@ def mno_rtd: Flag<["-"], "mno-rtd">, Group<m_Group>;
def mno_soft_float : Flag<["-"], "mno-soft-float">, Group<m_Group>;
def mno_stackrealign : Flag<["-"], "mno-stackrealign">, Group<m_Group>;
+def mrelax : Flag<["-"], "mrelax">, Group<m_riscv_Features_Group>,
+ HelpText<"Enable linker relaxation">;
+def mno_relax : Flag<["-"], "mno-relax">, Group<m_riscv_Features_Group>,
+ HelpText<"Disable linker relaxation">;
+
def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>,
HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">;
def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group<m_arm_Features_Group>,
@@ -1827,8 +2010,8 @@ def ffixed_r9 : Flag<["-"], "ffixed-r9">, Group<m_arm_Features_Group>,
HelpText<"Reserve the r9 register (ARM only)">;
def mno_movt : Flag<["-"], "mno-movt">, Group<m_arm_Features_Group>,
HelpText<"Disallow use of movt/movw pairs (ARM only)">;
-def mcrc : Flag<["-"], "mcrc">, Group<m_arm_Features_Group>,
- HelpText<"Allow use of CRC instructions (ARM only)">;
+def mcrc : Flag<["-"], "mcrc">, Group<m_Group>,
+ HelpText<"Allow use of CRC instructions (ARM/Mips only)">;
def mnocrc : Flag<["-"], "mnocrc">, Group<m_arm_Features_Group>,
HelpText<"Disallow use of CRC instructions (ARM only)">;
def mno_neg_immediates: Flag<["-"], "mno-neg-immediates">, Group<m_arm_Features_Group>,
@@ -1844,11 +2027,17 @@ def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">,
HelpText<"Don't workaround Cortex-A53 erratum 835769 (AArch64 only)">;
def ffixed_x18 : Flag<["-"], "ffixed-x18">, Group<m_aarch64_Features_Group>,
HelpText<"Reserve the x18 register (AArch64 only)">;
+def ffixed_x20 : Flag<["-"], "ffixed-x20">, Group<m_aarch64_Features_Group>,
+ HelpText<"Reserve the x20 register (AArch64 only)">;
def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>;
def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>;
def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group<m_wasm_Features_Group>;
def mno_nontrapping_fptoint : Flag<["-"], "mno-nontrapping-fptoint">, Group<m_wasm_Features_Group>;
+def msign_ext : Flag<["-"], "msign-ext">, Group<m_wasm_Features_Group>;
+def mno_sign_ext : Flag<["-"], "mno-sign-ext">, Group<m_wasm_Features_Group>;
+def mexception_handing : Flag<["-"], "mexception-handling">, Group<m_wasm_Features_Group>;
+def mno_exception_handing : Flag<["-"], "mno-exception-handling">, Group<m_wasm_Features_Group>;
def mamdgpu_debugger_abi : Joined<["-"], "mamdgpu-debugger-abi=">,
Flags<[HelpHidden]>,
@@ -1866,6 +2055,7 @@ def maltivec : Flag<["-"], "maltivec">, Group<m_ppc_Features_Group>;
def mno_altivec : Flag<["-"], "mno-altivec">, Group<m_ppc_Features_Group>;
def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>;
def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>;
+def msecure_plt : Flag<["-"], "msecure-plt">, Group<m_ppc_Features_Group>;
def mpower8_vector : Flag<["-"], "mpower8-vector">,
Group<m_ppc_Features_Group>;
def mno_power8_vector : Flag<["-"], "mno-power8-vector">,
@@ -1962,124 +2152,141 @@ def mpie_copy_relocations : Flag<["-"], "mpie-copy-relocations">, Group<m_Group>
def mno_pie_copy_relocations : Flag<["-"], "mno-pie-copy-relocations">, Group<m_Group>;
def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86 only)">,
Flags<[CC1Option]>, Group<m_Group>;
-def mips16 : Flag<["-"], "mips16">, Group<m_Group>;
-def mno_mips16 : Flag<["-"], "mno-mips16">, Group<m_Group>;
-def mmicromips : Flag<["-"], "mmicromips">, Group<m_Group>;
-def mno_micromips : Flag<["-"], "mno-micromips">, Group<m_Group>;
-def mxgot : Flag<["-"], "mxgot">, Group<m_Group>;
-def mno_xgot : Flag<["-"], "mno-xgot">, Group<m_Group>;
-def mldc1_sdc1 : Flag<["-"], "mldc1-sdc1">, Group<m_Group>;
-def mno_ldc1_sdc1 : Flag<["-"], "mno-ldc1-sdc1">, Group<m_Group>;
-def mcheck_zero_division : Flag<["-"], "mcheck-zero-division">, Group<m_Group>;
+def mips16 : Flag<["-"], "mips16">, Group<m_mips_Features_Group>;
+def mno_mips16 : Flag<["-"], "mno-mips16">, Group<m_mips_Features_Group>;
+def mmicromips : Flag<["-"], "mmicromips">, Group<m_mips_Features_Group>;
+def mno_micromips : Flag<["-"], "mno-micromips">, Group<m_mips_Features_Group>;
+def mxgot : Flag<["-"], "mxgot">, Group<m_mips_Features_Group>;
+def mno_xgot : Flag<["-"], "mno-xgot">, Group<m_mips_Features_Group>;
+def mldc1_sdc1 : Flag<["-"], "mldc1-sdc1">, Group<m_mips_Features_Group>;
+def mno_ldc1_sdc1 : Flag<["-"], "mno-ldc1-sdc1">, Group<m_mips_Features_Group>;
+def mcheck_zero_division : Flag<["-"], "mcheck-zero-division">,
+ Group<m_mips_Features_Group>;
def mno_check_zero_division : Flag<["-"], "mno-check-zero-division">,
- Group<m_Group>;
-def mcompact_branches_EQ : Joined<["-"], "mcompact-branches=">, Group<m_Group>;
+ Group<m_mips_Features_Group>;
+def mcompact_branches_EQ : Joined<["-"], "mcompact-branches=">,
+ Group<m_mips_Features_Group>;
def mbranch_likely : Flag<["-"], "mbranch-likely">, Group<m_Group>,
IgnoredGCCCompat;
def mno_branch_likely : Flag<["-"], "mno-branch-likely">, Group<m_Group>,
IgnoredGCCCompat;
-def mdsp : Flag<["-"], "mdsp">, Group<m_Group>;
-def mno_dsp : Flag<["-"], "mno-dsp">, Group<m_Group>;
-def mdspr2 : Flag<["-"], "mdspr2">, Group<m_Group>;
-def mno_dspr2 : Flag<["-"], "mno-dspr2">, Group<m_Group>;
-def msingle_float : Flag<["-"], "msingle-float">, Group<m_Group>;
-def mdouble_float : Flag<["-"], "mdouble-float">, Group<m_Group>;
-def mmadd4 : Flag<["-"], "mmadd4">, Group<m_Group>,
+def mindirect_jump_EQ : Joined<["-"], "mindirect-jump=">,
+ Group<m_mips_Features_Group>,
+ HelpText<"Change indirect jump instructions to inhibit speculation">;
+def mdsp : Flag<["-"], "mdsp">, Group<m_mips_Features_Group>;
+def mno_dsp : Flag<["-"], "mno-dsp">, Group<m_mips_Features_Group>;
+def mdspr2 : Flag<["-"], "mdspr2">, Group<m_mips_Features_Group>;
+def mno_dspr2 : Flag<["-"], "mno-dspr2">, Group<m_mips_Features_Group>;
+def msingle_float : Flag<["-"], "msingle-float">, Group<m_mips_Features_Group>;
+def mdouble_float : Flag<["-"], "mdouble-float">, Group<m_mips_Features_Group>;
+def mmadd4 : Flag<["-"], "mmadd4">, Group<m_mips_Features_Group>,
HelpText<"Enable the generation of 4-operand madd.s, madd.d and related instructions.">;
-def mno_madd4 : Flag<["-"], "mno-madd4">, Group<m_Group>,
+def mno_madd4 : Flag<["-"], "mno-madd4">, Group<m_mips_Features_Group>,
HelpText<"Disable the generation of 4-operand madd.s, madd.d and related instructions.">;
-def mmsa : Flag<["-"], "mmsa">, Group<m_Group>,
+def mmsa : Flag<["-"], "mmsa">, Group<m_mips_Features_Group>,
HelpText<"Enable MSA ASE (MIPS only)">;
-def mno_msa : Flag<["-"], "mno-msa">, Group<m_Group>,
+def mno_msa : Flag<["-"], "mno-msa">, Group<m_mips_Features_Group>,
HelpText<"Disable MSA ASE (MIPS only)">;
-def mmt : Flag<["-"], "mmt">, Group<m_Group>,
+def mmt : Flag<["-"], "mmt">, Group<m_mips_Features_Group>,
HelpText<"Enable MT ASE (MIPS only)">;
-def mno_mt : Flag<["-"], "mno-mt">, Group<m_Group>,
+def mno_mt : Flag<["-"], "mno-mt">, Group<m_mips_Features_Group>,
HelpText<"Disable MT ASE (MIPS only)">;
-def mfp64 : Flag<["-"], "mfp64">, Group<m_Group>,
+def mfp64 : Flag<["-"], "mfp64">, Group<m_mips_Features_Group>,
HelpText<"Use 64-bit floating point registers (MIPS only)">;
-def mfp32 : Flag<["-"], "mfp32">, Group<m_Group>,
+def mfp32 : Flag<["-"], "mfp32">, Group<m_mips_Features_Group>,
HelpText<"Use 32-bit floating point registers (MIPS only)">;
-def mgpopt : Flag<["-"], "mgpopt">, Group<m_Group>,
+def mgpopt : Flag<["-"], "mgpopt">, Group<m_mips_Features_Group>,
HelpText<"Use GP relative accesses for symbols known to be in a small"
" data section (MIPS)">;
-def mno_gpopt : Flag<["-"], "mno-gpopt">, Group<m_Group>,
+def mno_gpopt : Flag<["-"], "mno-gpopt">, Group<m_mips_Features_Group>,
HelpText<"Do not use GP relative accesses for symbols known to be in a small"
" data section (MIPS)">;
-def mlocal_sdata : Flag<["-"], "mlocal-sdata">, Group<m_Group>,
+def mlocal_sdata : Flag<["-"], "mlocal-sdata">,
+ Group<m_mips_Features_Group>,
HelpText<"Extend the -G behaviour to object local data (MIPS)">;
-def mno_local_sdata : Flag<["-"], "mno-local-sdata">, Group<m_Group>,
+def mno_local_sdata : Flag<["-"], "mno-local-sdata">,
+ Group<m_mips_Features_Group>,
HelpText<"Do not extend the -G behaviour to object local data (MIPS)">;
-def mextern_sdata : Flag<["-"], "mextern-sdata">, Group<m_Group>,
+def mextern_sdata : Flag<["-"], "mextern-sdata">,
+ Group<m_mips_Features_Group>,
HelpText<"Assume that externally defined data is in the small data if it"
" meets the -G <size> threshold (MIPS)">;
-def mno_extern_sdata : Flag<["-"], "mno-extern-sdata">, Group<m_Group>,
+def mno_extern_sdata : Flag<["-"], "mno-extern-sdata">,
+ Group<m_mips_Features_Group>,
HelpText<"Do not assume that externally defined data is in the small data if"
" it meets the -G <size> threshold (MIPS)">;
-def membedded_data : Flag<["-"], "membedded-data">, Group<m_Group>,
+def membedded_data : Flag<["-"], "membedded-data">,
+ Group<m_mips_Features_Group>,
HelpText<"Place constants in the .rodata section instead of the .sdata "
"section even if they meet the -G <size> threshold (MIPS)">;
-def mno_embedded_data : Flag<["-"], "mno-embedded-data">, Group<m_Group>,
+def mno_embedded_data : Flag<["-"], "mno-embedded-data">,
+ Group<m_mips_Features_Group>,
HelpText<"Do not place constants in the .rodata section instead of the "
".sdata if they meet the -G <size> threshold (MIPS)">;
-def mnan_EQ : Joined<["-"], "mnan=">, Group<m_Group>;
-def mabs_EQ : Joined<["-"], "mabs=">, Group<m_Group>;
-def mabicalls : Flag<["-"], "mabicalls">, Group<m_Group>,
+def mnan_EQ : Joined<["-"], "mnan=">, Group<m_mips_Features_Group>;
+def mabs_EQ : Joined<["-"], "mabs=">, Group<m_mips_Features_Group>;
+def mabicalls : Flag<["-"], "mabicalls">, Group<m_mips_Features_Group>,
HelpText<"Enable SVR4-style position-independent code (Mips only)">;
-def mno_abicalls : Flag<["-"], "mno-abicalls">, Group<m_Group>,
+def mno_abicalls : Flag<["-"], "mno-abicalls">, Group<m_mips_Features_Group>,
HelpText<"Disable SVR4-style position-independent code (Mips only)">;
+def mno_crc : Flag<["-"], "mno-crc">, Group<m_mips_Features_Group>,
+ HelpText<"Disallow use of CRC instructions (Mips only)">;
+def mvirt : Flag<["-"], "mvirt">, Group<m_mips_Features_Group>;
+def mno_virt : Flag<["-"], "mno-virt">, Group<m_mips_Features_Group>;
+def mginv : Flag<["-"], "mginv">, Group<m_mips_Features_Group>;
+def mno_ginv : Flag<["-"], "mno-ginv">, Group<m_mips_Features_Group>;
def mips1 : Flag<["-"], "mips1">,
- Alias<march_EQ>, AliasArgs<["mips1"]>,
+ Alias<march_EQ>, AliasArgs<["mips1"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips1">, Flags<[HelpHidden]>;
def mips2 : Flag<["-"], "mips2">,
- Alias<march_EQ>, AliasArgs<["mips2"]>,
+ Alias<march_EQ>, AliasArgs<["mips2"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips2">, Flags<[HelpHidden]>;
def mips3 : Flag<["-"], "mips3">,
- Alias<march_EQ>, AliasArgs<["mips3"]>,
+ Alias<march_EQ>, AliasArgs<["mips3"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips3">, Flags<[HelpHidden]>;
def mips4 : Flag<["-"], "mips4">,
- Alias<march_EQ>, AliasArgs<["mips4"]>,
+ Alias<march_EQ>, AliasArgs<["mips4"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips4">, Flags<[HelpHidden]>;
def mips5 : Flag<["-"], "mips5">,
- Alias<march_EQ>, AliasArgs<["mips5"]>,
+ Alias<march_EQ>, AliasArgs<["mips5"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips5">, Flags<[HelpHidden]>;
def mips32 : Flag<["-"], "mips32">,
- Alias<march_EQ>, AliasArgs<["mips32"]>,
+ Alias<march_EQ>, AliasArgs<["mips32"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips32">, Flags<[HelpHidden]>;
def mips32r2 : Flag<["-"], "mips32r2">,
- Alias<march_EQ>, AliasArgs<["mips32r2"]>,
+ Alias<march_EQ>, AliasArgs<["mips32r2"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips32r2">, Flags<[HelpHidden]>;
def mips32r3 : Flag<["-"], "mips32r3">,
- Alias<march_EQ>, AliasArgs<["mips32r3"]>,
+ Alias<march_EQ>, AliasArgs<["mips32r3"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips32r3">, Flags<[HelpHidden]>;
def mips32r5 : Flag<["-"], "mips32r5">,
- Alias<march_EQ>, AliasArgs<["mips32r5"]>,
+ Alias<march_EQ>, AliasArgs<["mips32r5"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips32r5">, Flags<[HelpHidden]>;
def mips32r6 : Flag<["-"], "mips32r6">,
- Alias<march_EQ>, AliasArgs<["mips32r6"]>,
+ Alias<march_EQ>, AliasArgs<["mips32r6"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips32r6">, Flags<[HelpHidden]>;
def mips64 : Flag<["-"], "mips64">,
- Alias<march_EQ>, AliasArgs<["mips64"]>,
+ Alias<march_EQ>, AliasArgs<["mips64"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips64">, Flags<[HelpHidden]>;
def mips64r2 : Flag<["-"], "mips64r2">,
- Alias<march_EQ>, AliasArgs<["mips64r2"]>,
+ Alias<march_EQ>, AliasArgs<["mips64r2"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips64r2">, Flags<[HelpHidden]>;
def mips64r3 : Flag<["-"], "mips64r3">,
- Alias<march_EQ>, AliasArgs<["mips64r3"]>,
+ Alias<march_EQ>, AliasArgs<["mips64r3"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips64r3">, Flags<[HelpHidden]>;
def mips64r5 : Flag<["-"], "mips64r5">,
- Alias<march_EQ>, AliasArgs<["mips64r5"]>,
+ Alias<march_EQ>, AliasArgs<["mips64r5"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips64r5">, Flags<[HelpHidden]>;
def mips64r6 : Flag<["-"], "mips64r6">,
- Alias<march_EQ>, AliasArgs<["mips64r6"]>,
+ Alias<march_EQ>, AliasArgs<["mips64r6"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips64r6">, Flags<[HelpHidden]>;
-def mfpxx : Flag<["-"], "mfpxx">, Group<m_Group>,
+def mfpxx : Flag<["-"], "mfpxx">, Group<m_mips_Features_Group>,
HelpText<"Avoid FPU mode dependent operations when used with the O32 ABI">,
Flags<[HelpHidden]>;
-def modd_spreg : Flag<["-"], "modd-spreg">, Group<m_Group>,
+def modd_spreg : Flag<["-"], "modd-spreg">, Group<m_mips_Features_Group>,
HelpText<"Enable odd single-precision floating point registers">,
Flags<[HelpHidden]>;
-def mno_odd_spreg : Flag<["-"], "mno-odd-spreg">, Group<m_Group>,
+def mno_odd_spreg : Flag<["-"], "mno-odd-spreg">, Group<m_mips_Features_Group>,
HelpText<"Disable odd single-precision floating point registers">,
Flags<[HelpHidden]>;
def mglibc : Flag<["-"], "mglibc">, Group<m_libc_Group>, Flags<[HelpHidden]>;
@@ -2092,7 +2299,7 @@ def multi__module : Flag<["-"], "multi_module">;
def multiply__defined__unused : Separate<["-"], "multiply_defined_unused">;
def multiply__defined : Separate<["-"], "multiply_defined">;
def mwarn_nonportable_cfstrings : Flag<["-"], "mwarn-nonportable-cfstrings">, Group<m_Group>;
-def no_canonical_prefixes : Flag<["-"], "no-canonical-prefixes">, Flags<[HelpHidden]>,
+def no_canonical_prefixes : Flag<["-"], "no-canonical-prefixes">, Flags<[HelpHidden, CoreOption]>,
HelpText<"Use relative instead of canonical paths">;
def no_cpp_precomp : Flag<["-"], "no-cpp-precomp">, Group<clang_ignored_f_Group>;
def no_integrated_cpp : Flag<["-", "--"], "no-integrated-cpp">, Flags<[DriverOption]>;
@@ -2175,7 +2382,7 @@ def fno_rtlib_add_rpath: Flag<["-"], "fno-rtlib-add-rpath">, Flags<[NoArgumentUn
HelpText<"Do not add -rpath with architecture-specific resource directory to the linker flags">;
def r : Flag<["-"], "r">, Flags<[LinkerInput,NoArgumentUnused]>,
Group<Link_Group>;
-def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[DriverOption]>,
+def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[CC1Option, DriverOption]>,
HelpText<"Save intermediate compilation results.">;
def save_temps : Flag<["-", "--"], "save-temps">, Flags<[DriverOption]>,
Alias<save_temps_EQ>, AliasArgs<["cwd"]>,
@@ -2326,7 +2533,8 @@ def _for_linker_EQ : Joined<["--"], "for-linker=">, Alias<Xlinker>;
def _for_linker : Separate<["--"], "for-linker">, Alias<Xlinker>;
def _force_link_EQ : Joined<["--"], "force-link=">, Alias<u>;
def _force_link : Separate<["--"], "force-link">, Alias<u>;
-def _help_hidden : Flag<["--"], "help-hidden">;
+def _help_hidden : Flag<["--"], "help-hidden">,
+ HelpText<"Display help for hidden options">;
def _imacros_EQ : Joined<["--"], "imacros=">, Alias<imacros>;
def _include_barrier : Flag<["--"], "include-barrier">, Alias<I_>;
def _include_directory_after_EQ : Joined<["--"], "include-directory-after=">, Alias<idirafter>;
@@ -2396,39 +2604,50 @@ def _write_dependencies : Flag<["--"], "write-dependencies">, Alias<MD>;
def _write_user_dependencies : Flag<["--"], "write-user-dependencies">, Alias<MMD>;
def _ : Joined<["--"], "">, Flags<[Unsupported]>;
-def mieee_rnd_near : Flag<["-"], "mieee-rnd-near">, Group<m_hexagon_Features_Group>;
+// Hexagon feature flags.
+def mieee_rnd_near : Flag<["-"], "mieee-rnd-near">,
+ Group<m_hexagon_Features_Group>;
def mv4 : Flag<["-"], "mv4">, Group<m_hexagon_Features_Group>,
- Alias<mcpu_EQ>, AliasArgs<["hexagonv4"]>;
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv4"]>;
def mv5 : Flag<["-"], "mv5">, Group<m_hexagon_Features_Group>, Alias<mcpu_EQ>,
- AliasArgs<["hexagonv5"]>;
+ AliasArgs<["hexagonv5"]>;
def mv55 : Flag<["-"], "mv55">, Group<m_hexagon_Features_Group>,
- Alias<mcpu_EQ>, AliasArgs<["hexagonv55"]>;
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv55"]>;
def mv60 : Flag<["-"], "mv60">, Group<m_hexagon_Features_Group>,
- Alias<mcpu_EQ>, AliasArgs<["hexagonv60"]>;
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv60"]>;
def mv62 : Flag<["-"], "mv62">, Group<m_hexagon_Features_Group>,
- Alias<mcpu_EQ>, AliasArgs<["hexagonv62"]>;
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv62"]>;
def mv65 : Flag<["-"], "mv65">, Group<m_hexagon_Features_Group>,
- Alias<mcpu_EQ>, AliasArgs<["hexagonv65"]>;
-def mhexagon_hvx : Flag<[ "-" ], "mhvx">,
- Group<m_hexagon_Features_HVX_Group>,
- HelpText<"Enable Hexagon Vector eXtensions">;
-def mhexagon_hvx_EQ : Joined<[ "-" ], "mhvx=">,
- Group<m_hexagon_Features_HVX_Group>,
- HelpText<"Enable Hexagon Vector eXtensions">;
-def mno_hexagon_hvx : Flag<[ "-" ], "mno-hvx">,
- Group<m_hexagon_Features_HVX_Group>,
- HelpText<"Disable Hexagon Vector eXtensions">;
-def mhexagon_hvx_length_EQ : Joined<[ "-" ], "mhvx-length=">,
- Group<m_hexagon_Features_HVX_Group>,
- HelpText<"Set Hexagon Vector Length">, Values<"64B,128B">;
-// hvx-double deprecrated flag.
-def mhexagon_hvx_double : Flag<[ "-" ], "mhvx-double">,
- Group<m_hexagon_Features_HVX_Group>,
- HelpText<"Enable Hexagon Double Vector eXtensions">;
-def mno_hexagon_hvx_double
- : Flag<[ "-" ], "mno-hvx-double">,
- Group<m_hexagon_Features_HVX_Group>,
- HelpText<"Disable Hexagon Double Vector eXtensions">;
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv65"]>;
+def mhexagon_hvx : Flag<["-"], "mhvx">, Group<m_hexagon_Features_HVX_Group>,
+ HelpText<"Enable Hexagon Vector eXtensions">;
+def mhexagon_hvx_EQ : Joined<["-"], "mhvx=">,
+ Group<m_hexagon_Features_HVX_Group>,
+ HelpText<"Enable Hexagon Vector eXtensions">;
+def mno_hexagon_hvx : Flag<["-"], "mno-hvx">,
+ Group<m_hexagon_Features_HVX_Group>,
+ HelpText<"Disable Hexagon Vector eXtensions">;
+def mhexagon_hvx_length_EQ : Joined<["-"], "mhvx-length=">,
+ Group<m_hexagon_Features_HVX_Group>, HelpText<"Set Hexagon Vector Length">,
+ Values<"64B,128B">;
+def ffixed_r19: Flag<["-"], "ffixed-r19">,
+ HelpText<"Reserve register r19 (Hexagon only)">;
+def mmemops : Flag<["-"], "mmemops">, Group<m_hexagon_Features_Group>,
+ Flags<[CC1Option]>, HelpText<"Enable generation of memop instructions">;
+def mno_memops : Flag<["-"], "mno-memops">, Group<m_hexagon_Features_Group>,
+ Flags<[CC1Option]>, HelpText<"Disable generation of memop instructions">;
+def mpackets : Flag<["-"], "mpackets">, Group<m_hexagon_Features_Group>,
+ Flags<[CC1Option]>, HelpText<"Enable generation of instruction packets">;
+def mno_packets : Flag<["-"], "mno-packets">, Group<m_hexagon_Features_Group>,
+ Flags<[CC1Option]>, HelpText<"Disable generation of instruction packets">;
+def mnvj : Flag<["-"], "mnvj">, Group<m_hexagon_Features_Group>,
+ Flags<[CC1Option]>, HelpText<"Enable generation of new-value jumps">;
+def mno_nvj : Flag<["-"], "mno-nvj">, Group<m_hexagon_Features_Group>,
+ Flags<[CC1Option]>, HelpText<"Disable generation of new-value jumps">;
+def mnvs : Flag<["-"], "mnvs">, Group<m_hexagon_Features_Group>,
+ Flags<[CC1Option]>, HelpText<"Enable generation of new-value stores">;
+def mno_nvs : Flag<["-"], "mno-nvs">, Group<m_hexagon_Features_Group>,
+ Flags<[CC1Option]>, HelpText<"Disable generation of new-value stores">;
// X86 feature flags
@@ -2499,10 +2718,14 @@ def mbmi : Flag<["-"], "mbmi">, Group<m_x86_Features_Group>;
def mno_bmi : Flag<["-"], "mno-bmi">, Group<m_x86_Features_Group>;
def mbmi2 : Flag<["-"], "mbmi2">, Group<m_x86_Features_Group>;
def mno_bmi2 : Flag<["-"], "mno-bmi2">, Group<m_x86_Features_Group>;
+def mcldemote : Flag<["-"], "mcldemote">, Group<m_x86_Features_Group>;
+def mno_cldemote : Flag<["-"], "mno-cldemote">, Group<m_x86_Features_Group>;
def mclflushopt : Flag<["-"], "mclflushopt">, Group<m_x86_Features_Group>;
def mno_clflushopt : Flag<["-"], "mno-clflushopt">, Group<m_x86_Features_Group>;
def mclwb : Flag<["-"], "mclwb">, Group<m_x86_Features_Group>;
def mno_clwb : Flag<["-"], "mno-clwb">, Group<m_x86_Features_Group>;
+def mwbnoinvd : Flag<["-"], "mwbnoinvd">, Group<m_x86_Features_Group>;
+def mno_wbnoinvd : Flag<["-"], "mno-wbnoinvd">, Group<m_x86_Features_Group>;
def mclzero : Flag<["-"], "mclzero">, Group<m_x86_Features_Group>;
def mno_clzero : Flag<["-"], "mno-clzero">, Group<m_x86_Features_Group>;
def mcx16 : Flag<["-"], "mcx16">, Group<m_x86_Features_Group>;
@@ -2517,6 +2740,8 @@ def mfsgsbase : Flag<["-"], "mfsgsbase">, Group<m_x86_Features_Group>;
def mno_fsgsbase : Flag<["-"], "mno-fsgsbase">, Group<m_x86_Features_Group>;
def mfxsr : Flag<["-"], "mfxsr">, Group<m_x86_Features_Group>;
def mno_fxsr : Flag<["-"], "mno-fxsr">, Group<m_x86_Features_Group>;
+def minvpcid : Flag<["-"], "minvpcid">, Group<m_x86_Features_Group>;
+def mno_invpcid : Flag<["-"], "mno-invpcid">, Group<m_x86_Features_Group>;
def mgfni : Flag<["-"], "mgfni">, Group<m_x86_Features_Group>;
def mno_gfni : Flag<["-"], "mno-gfni">, Group<m_x86_Features_Group>;
def mlwp : Flag<["-"], "mlwp">, Group<m_x86_Features_Group>;
@@ -2525,6 +2750,10 @@ def mlzcnt : Flag<["-"], "mlzcnt">, Group<m_x86_Features_Group>;
def mno_lzcnt : Flag<["-"], "mno-lzcnt">, Group<m_x86_Features_Group>;
def mmovbe : Flag<["-"], "mmovbe">, Group<m_x86_Features_Group>;
def mno_movbe : Flag<["-"], "mno-movbe">, Group<m_x86_Features_Group>;
+def mmovdiri : Flag<["-"], "mmovdiri">, Group<m_x86_Features_Group>;
+def mno_movdiri : Flag<["-"], "mno-movdiri">, Group<m_x86_Features_Group>;
+def mmovdir64b : Flag<["-"], "mmovdir64b">, Group<m_x86_Features_Group>;
+def mno_movdir64b : Flag<["-"], "mno-movdir64b">, Group<m_x86_Features_Group>;
def mmpx : Flag<["-"], "mmpx">, Group<m_x86_Features_Group>;
def mno_mpx : Flag<["-"], "mno-mpx">, Group<m_x86_Features_Group>;
def mmwaitx : Flag<["-"], "mmwaitx">, Group<m_x86_Features_Group>;
@@ -2533,18 +2762,26 @@ def mpku : Flag<["-"], "mpku">, Group<m_x86_Features_Group>;
def mno_pku : Flag<["-"], "mno-pku">, Group<m_x86_Features_Group>;
def mpclmul : Flag<["-"], "mpclmul">, Group<m_x86_Features_Group>;
def mno_pclmul : Flag<["-"], "mno-pclmul">, Group<m_x86_Features_Group>;
+def mpconfig : Flag<["-"], "mpconfig">, Group<m_x86_Features_Group>;
+def mno_pconfig : Flag<["-"], "mno-pconfig">, Group<m_x86_Features_Group>;
def mpopcnt : Flag<["-"], "mpopcnt">, Group<m_x86_Features_Group>;
def mno_popcnt : Flag<["-"], "mno-popcnt">, Group<m_x86_Features_Group>;
def mprefetchwt1 : Flag<["-"], "mprefetchwt1">, Group<m_x86_Features_Group>;
def mno_prefetchwt1 : Flag<["-"], "mno-prefetchwt1">, Group<m_x86_Features_Group>;
def mprfchw : Flag<["-"], "mprfchw">, Group<m_x86_Features_Group>;
def mno_prfchw : Flag<["-"], "mno-prfchw">, Group<m_x86_Features_Group>;
+def mptwrite : Flag<["-"], "mptwrite">, Group<m_x86_Features_Group>;
+def mno_ptwrite : Flag<["-"], "mno-ptwrite">, Group<m_x86_Features_Group>;
+def mrdpid : Flag<["-"], "mrdpid">, Group<m_x86_Features_Group>;
+def mno_rdpid : Flag<["-"], "mno-rdpid">, Group<m_x86_Features_Group>;
def mrdrnd : Flag<["-"], "mrdrnd">, Group<m_x86_Features_Group>;
def mno_rdrnd : Flag<["-"], "mno-rdrnd">, Group<m_x86_Features_Group>;
def mrtm : Flag<["-"], "mrtm">, Group<m_x86_Features_Group>;
def mno_rtm : Flag<["-"], "mno-rtm">, Group<m_x86_Features_Group>;
def mrdseed : Flag<["-"], "mrdseed">, Group<m_x86_Features_Group>;
def mno_rdseed : Flag<["-"], "mno-rdseed">, Group<m_x86_Features_Group>;
+def msahf : Flag<["-"], "msahf">, Group<m_x86_Features_Group>;
+def mno_sahf : Flag<["-"], "mno-sahf">, Group<m_x86_Features_Group>;
def msgx : Flag<["-"], "msgx">, Group<m_x86_Features_Group>;
def mno_sgx : Flag<["-"], "mno-sgx">, Group<m_x86_Features_Group>;
def msha : Flag<["-"], "msha">, Group<m_x86_Features_Group>;
@@ -2555,6 +2792,8 @@ def mvaes : Flag<["-"], "mvaes">, Group<m_x86_Features_Group>;
def mno_vaes : Flag<["-"], "mno-vaes">, Group<m_x86_Features_Group>;
def mvpclmulqdq : Flag<["-"], "mvpclmulqdq">, Group<m_x86_Features_Group>;
def mno_vpclmulqdq : Flag<["-"], "mno-vpclmulqdq">, Group<m_x86_Features_Group>;
+def mwaitpkg : Flag<["-"], "mwaitpkg">, Group<m_x86_Features_Group>;
+def mno_waitpkg : Flag<["-"], "mno-waitpkg">, Group<m_x86_Features_Group>;
def mxop : Flag<["-"], "mxop">, Group<m_x86_Features_Group>;
def mno_xop : Flag<["-"], "mno-xop">, Group<m_x86_Features_Group>;
def mxsave : Flag<["-"], "mxsave">, Group<m_x86_Features_Group>;
@@ -2567,8 +2806,10 @@ def mxsaves : Flag<["-"], "mxsaves">, Group<m_x86_Features_Group>;
def mno_xsaves : Flag<["-"], "mno-xsaves">, Group<m_x86_Features_Group>;
def mshstk : Flag<["-"], "mshstk">, Group<m_x86_Features_Group>;
def mno_shstk : Flag<["-"], "mno-shstk">, Group<m_x86_Features_Group>;
-def mibt : Flag<["-"], "mibt">, Group<m_x86_Features_Group>;
-def mno_ibt : Flag<["-"], "mno-ibt">, Group<m_x86_Features_Group>;
+def mretpoline : Flag<["-"], "mretpoline">, Group<m_x86_Features_Group>;
+def mno_retpoline : Flag<["-"], "mno-retpoline">, Group<m_x86_Features_Group>;
+def mretpoline_external_thunk : Flag<["-"], "mretpoline-external-thunk">, Group<m_x86_Features_Group>;
+def mno_retpoline_external_thunk : Flag<["-"], "mno-retpoline-external-thunk">, Group<m_x86_Features_Group>;
// These are legacy user-facing driver-level option spellings. They are always
// aliases for options that are spelled using the more common Unix / GNU flag
@@ -2604,8 +2845,6 @@ def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<f_Group>;
def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>, Flags<[CoreOption]>;
-defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
-def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<clang_ignored_gcc_optimization_f_Group>;
defm align_labels : BooleanFFlag<"align-labels">, Group<clang_ignored_gcc_optimization_f_Group>;
def falign_labels_EQ : Joined<["-"], "falign-labels=">, Group<clang_ignored_gcc_optimization_f_Group>;
defm align_loops : BooleanFFlag<"align-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
@@ -2623,8 +2862,6 @@ defm reorder_blocks : BooleanFFlag<"reorder-blocks">, Group<clang_ignored_gcc_op
defm eliminate_unused_debug_types : BooleanFFlag<"eliminate-unused-debug-types">, Group<clang_ignored_f_Group>;
defm branch_count_reg : BooleanFFlag<"branch-count-reg">, Group<clang_ignored_gcc_optimization_f_Group>;
defm default_inline : BooleanFFlag<"default-inline">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm delete_null_pointer_checks : BooleanFFlag<"delete-null-pointer-checks">,
- Group<clang_ignored_gcc_optimization_f_Group>;
defm fat_lto_objects : BooleanFFlag<"fat-lto-objects">, Group<clang_ignored_gcc_optimization_f_Group>;
defm float_store : BooleanFFlag<"float-store">, Group<clang_ignored_gcc_optimization_f_Group>;
defm friend_injection : BooleanFFlag<"friend-injection">, Group<clang_ignored_f_Group>;
@@ -2634,7 +2871,6 @@ defm gcse_after_reload: BooleanFFlag<"gcse-after-reload">, Group<clang_ignored_g
defm gcse_las: BooleanFFlag<"gcse-las">, Group<clang_ignored_gcc_optimization_f_Group>;
defm gcse_sm: BooleanFFlag<"gcse-sm">, Group<clang_ignored_gcc_optimization_f_Group>;
defm gnu : BooleanFFlag<"gnu">, Group<clang_ignored_f_Group>;
-defm ident : BooleanFFlag<"ident">, Group<clang_ignored_f_Group>;
defm implicit_templates : BooleanFFlag<"implicit-templates">, Group<clang_ignored_f_Group>;
defm implement_inlines : BooleanFFlag<"implement-inlines">, Group<clang_ignored_f_Group>;
defm merge_constants : BooleanFFlag<"merge-constants">, Group<clang_ignored_gcc_optimization_f_Group>;
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
index a31ac05afc1bb..d144e488b56bb 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -30,7 +30,7 @@ class SanitizerArgs {
std::vector<std::string> ExtraDeps;
int CoverageFeatures = 0;
int MsanTrackOrigins = 0;
- bool MsanUseAfterDtor = false;
+ bool MsanUseAfterDtor = true;
bool CfiCrossDso = false;
bool CfiICallGeneralizePointers = false;
int AsanFieldPadding = 0;
diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h
index 8f76e17c48bae..b02ac66d3b5cf 100644
--- a/include/clang/Driver/Tool.h
+++ b/include/clang/Driver/Tool.h
@@ -88,12 +88,12 @@ public:
virtual bool hasIntegratedCPP() const = 0;
virtual bool isLinkJob() const { return false; }
virtual bool isDsymutilJob() const { return false; }
- /// \brief Returns the level of support for response files of this tool,
+ /// Returns the level of support for response files of this tool,
/// whether it accepts arguments to be passed via a file on disk.
ResponseFileSupport getResponseFilesSupport() const {
return ResponseSupport;
}
- /// \brief Returns which encoding the response file should use. This is only
+ /// Returns which encoding the response file should use. This is only
/// relevant on Windows platforms where there are different encodings being
/// accepted for different tools. On UNIX, UTF8 is universal.
///
@@ -108,11 +108,11 @@ public:
llvm::sys::WindowsEncodingMethod getResponseFileEncoding() const {
return ResponseEncoding;
}
- /// \brief Returns which prefix to use when passing the name of a response
+ /// Returns which prefix to use when passing the name of a response
/// file as a parameter to this tool.
const char *getResponseFileFlag() const { return ResponseFlag; }
- /// \brief Does this tool have "good" standardized diagnostics, or should the
+ /// Does this tool have "good" standardized diagnostics, or should the
/// driver add an additional "command failed" diagnostic on failures.
virtual bool hasGoodDiagnostics() const { return false; }
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 13f54d3718b4c..addf7aa6a9c8d 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -1,4 +1,4 @@
-//===--- ToolChain.h - Collections of tools for one platform ----*- C++ -*-===//
+//===- ToolChain.h - Collections of tools for one platform ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,69 +10,84 @@
#ifndef LLVM_CLANG_DRIVER_TOOLCHAIN_H
#define LLVM_CLANG_DRIVER_TOOLCHAIN_H
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/Sanitizers.h"
-#include "clang/Basic/VersionTuple.h"
#include "clang/Driver/Action.h"
#include "clang/Driver/Multilib.h"
#include "clang/Driver/Types.h"
-#include "clang/Driver/Util.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/VersionTuple.h"
#include "llvm/Target/TargetOptions.h"
+#include <cassert>
#include <memory>
#include <string>
+#include <utility>
namespace llvm {
namespace opt {
- class ArgList;
- class DerivedArgList;
- class InputArgList;
-}
-}
+
+class Arg;
+class ArgList;
+class DerivedArgList;
+
+} // namespace opt
+} // namespace llvm
namespace clang {
+
class ObjCRuntime;
+
namespace vfs {
+
class FileSystem;
-}
+
+} // namespace vfs
namespace driver {
- class Compilation;
- class CudaInstallationDetector;
- class Driver;
- class InputInfo;
- class JobAction;
- class RegisterEffectiveTriple;
- class SanitizerArgs;
- class Tool;
- class XRayArgs;
+
+class Driver;
+class InputInfo;
+class SanitizerArgs;
+class Tool;
+class XRayArgs;
/// Helper structure used to pass information extracted from clang executable
/// name such as `i686-linux-android-g++`.
-///
struct ParsedClangName {
/// Target part of the executable name, as `i686-linux-android`.
std::string TargetPrefix;
+
/// Driver mode part of the executable name, as `g++`.
std::string ModeSuffix;
+
/// Corresponding driver mode argument, as '--driver-mode=g++'
- const char *DriverMode;
+ const char *DriverMode = nullptr;
+
/// True if TargetPrefix is recognized as a registered target name.
- bool TargetIsValid;
+ bool TargetIsValid = false;
- ParsedClangName() : DriverMode(nullptr), TargetIsValid(false) {}
+ ParsedClangName() = default;
ParsedClangName(std::string Suffix, const char *Mode)
- : ModeSuffix(Suffix), DriverMode(Mode), TargetIsValid(false) {}
+ : ModeSuffix(Suffix), DriverMode(Mode) {}
ParsedClangName(std::string Target, std::string Suffix, const char *Mode,
bool IsRegistered)
: TargetPrefix(Target), ModeSuffix(Suffix), DriverMode(Mode),
TargetIsValid(IsRegistered) {}
+
+ bool isEmpty() const {
+ return TargetPrefix.empty() && ModeSuffix.empty() && DriverMode == nullptr;
+ }
};
/// ToolChain - Access to tools for a single platform.
class ToolChain {
public:
- typedef SmallVector<std::string, 16> path_list;
+ using path_list = SmallVector<std::string, 16>;
enum CXXStdlibType {
CST_Libcxx,
@@ -85,32 +100,33 @@ public:
};
enum RTTIMode {
- RM_EnabledExplicitly,
- RM_EnabledImplicitly,
- RM_DisabledExplicitly,
- RM_DisabledImplicitly
+ RM_Enabled,
+ RM_Disabled,
};
private:
+ friend class RegisterEffectiveTriple;
+
const Driver &D;
llvm::Triple Triple;
const llvm::opt::ArgList &Args;
+
// We need to initialize CachedRTTIArg before CachedRTTIMode
const llvm::opt::Arg *const CachedRTTIArg;
+
const RTTIMode CachedRTTIMode;
- /// The list of toolchain specific path prefixes to search for
- /// files.
+ /// The list of toolchain specific path prefixes to search for files.
path_list FilePaths;
- /// The list of toolchain specific path prefixes to search for
- /// programs.
+ /// The list of toolchain specific path prefixes to search for programs.
path_list ProgramPaths;
mutable std::unique_ptr<Tool> Clang;
mutable std::unique_ptr<Tool> Assemble;
mutable std::unique_ptr<Tool> Link;
mutable std::unique_ptr<Tool> OffloadBundler;
+
Tool *getClang() const;
Tool *getAssemble() const;
Tool *getLink() const;
@@ -128,8 +144,6 @@ private:
EffectiveTriple = std::move(ET);
}
- friend class RegisterEffectiveTriple;
-
protected:
MultilibSet Multilibs;
@@ -185,7 +199,7 @@ public:
StringRef getPlatform() const { return Triple.getVendorName(); }
StringRef getOS() const { return Triple.getOSName(); }
- /// \brief Provide the default architecture name (as expected by -arch) for
+ /// Provide the default architecture name (as expected by -arch) for
/// this toolchain.
StringRef getDefaultUniversalArchName() const;
@@ -217,7 +231,7 @@ public:
// Returns the RTTIMode for the toolchain with the current arguments.
RTTIMode getRTTIMode() const { return CachedRTTIMode; }
- /// \brief Return any implicit target and/or mode flag for an invocation of
+ /// Return any implicit target and/or mode flag for an invocation of
/// the compiler driver as `ProgName`.
///
/// For example, when called with i686-linux-android-g++, the first element
@@ -231,7 +245,6 @@ public:
/// e.g., argv[0]).
/// \return A structure of type ParsedClangName that contains the executable
/// name parts.
- ///
static ParsedClangName getTargetAndModeFromProgramName(StringRef ProgName);
// Tool access.
@@ -272,7 +285,7 @@ public:
/// the linker suffix or name.
std::string GetLinkerPath() const;
- /// \brief Dispatch to the specific toolchain for verbose printing.
+ /// Dispatch to the specific toolchain for verbose printing.
///
/// This is used when handling the verbose option to print detailed,
/// toolchain-specific information useful for understanding the behavior of
@@ -281,7 +294,7 @@ public:
// Platform defaults information
- /// \brief Returns true if the toolchain is targeting a non-native
+ /// Returns true if the toolchain is targeting a non-native
/// architecture.
virtual bool isCrossCompiling() const;
@@ -300,7 +313,7 @@ public:
/// by default.
virtual bool IsIntegratedAssemblerDefault() const { return false; }
- /// \brief Check if the toolchain should use the integrated assembler.
+ /// Check if the toolchain should use the integrated assembler.
virtual bool useIntegratedAs() const;
/// IsMathErrnoDefault - Does this tool chain use -fmath-errno by default.
@@ -318,7 +331,7 @@ public:
/// mixed dispatch method be used?
virtual bool UseObjCMixedDispatch() const { return false; }
- /// \brief Check whether to enable x86 relax relocations by default.
+ /// Check whether to enable x86 relax relocations by default.
virtual bool useRelaxRelocations() const;
/// GetDefaultStackProtectorLevel - Get the default stack protector level for
@@ -328,9 +341,7 @@ public:
}
/// GetDefaultLinker - Get the default linker to use.
- virtual const char *getDefaultLinker() const {
- return "ld";
- }
+ virtual const char *getDefaultLinker() const { return "ld"; }
/// GetDefaultRuntimeLibType - Get the default runtime library variant to use.
virtual RuntimeLibType GetDefaultRuntimeLibType() const {
@@ -355,6 +366,9 @@ public:
// as OpenMP) to find arch-specific libraries.
std::string getArchSpecificLibPath() const;
+ // Returns <OSname> part of above.
+ StringRef getOSLibName() const;
+
/// needsProfileRT - returns true if instrumentation profile is on.
static bool needsProfileRT(const llvm::opt::ArgList &Args);
@@ -362,13 +376,13 @@ public:
/// by default.
virtual bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const;
- /// \brief Test whether this toolchain defaults to PIC.
+ /// Test whether this toolchain defaults to PIC.
virtual bool isPICDefault() const = 0;
- /// \brief Test whether this toolchain defaults to PIE.
+ /// Test whether this toolchain defaults to PIE.
virtual bool isPIEDefault() const = 0;
- /// \brief Tests whether this toolchain forces its default for PIC, PIE or
+ /// Tests whether this toolchain forces its default for PIC, PIE or
/// non-PIC. If this returns true, any PIC related flags should be ignored
/// and instead the results of \c isPICDefault() and \c isPIEDefault() are
/// used exclusively.
@@ -404,9 +418,7 @@ public:
GetExceptionModel(const llvm::opt::ArgList &Args) const;
/// SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode.
- virtual bool SupportsEmbeddedBitcode() const {
- return false;
- }
+ virtual bool SupportsEmbeddedBitcode() const { return false; }
/// getThreadModel() - Which thread model does this target use?
virtual std::string getThreadModel() const { return "posix"; }
@@ -442,7 +454,7 @@ public:
/// FIXME: this really belongs on some sort of DeploymentTarget abstraction
virtual bool hasBlocksRuntime() const { return true; }
- /// \brief Add the clang cc1 arguments for system include paths.
+ /// Add the clang cc1 arguments for system include paths.
///
/// This routine is responsible for adding the necessary cc1 arguments to
/// include headers from standard system header directories.
@@ -450,12 +462,12 @@ public:
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
- /// \brief Add options that need to be passed to cc1 for this target.
+ /// Add options that need to be passed to cc1 for this target.
virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
Action::OffloadKind DeviceOffloadKind) const;
- /// \brief Add warning options that need to be passed to cc1 for this target.
+ /// Add warning options that need to be passed to cc1 for this target.
virtual void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const;
// GetRuntimeLibType - Determine the runtime library type to use with the
@@ -497,27 +509,28 @@ public:
/// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags.
virtual bool AddFastMathRuntimeIfAvailable(
const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const;
+
/// addProfileRTLibs - When -fprofile-instr-profile is specified, try to pass
/// a suitable profile runtime library to the linker.
virtual void addProfileRTLibs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
- /// \brief Add arguments to use system-specific CUDA includes.
+ /// Add arguments to use system-specific CUDA includes.
virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
- /// \brief Add arguments to use MCU GCC toolchain includes.
+ /// Add arguments to use MCU GCC toolchain includes.
virtual void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
- /// \brief On Windows, returns the MSVC compatibility version.
+ /// On Windows, returns the MSVC compatibility version.
virtual VersionTuple computeMSVCVersion(const Driver *D,
const llvm::opt::ArgList &Args) const;
- /// \brief Return sanitizers which are available in this toolchain.
+ /// Return sanitizers which are available in this toolchain.
virtual SanitizerMask getSupportedSanitizers() const;
- /// \brief Return sanitizers which are enabled by default.
+ /// Return sanitizers which are enabled by default.
virtual SanitizerMask getDefaultSanitizers() const { return 0; }
};
@@ -534,7 +547,8 @@ public:
~RegisterEffectiveTriple() { TC.setEffectiveTriple(llvm::Triple()); }
};
-} // end namespace driver
-} // end namespace clang
+} // namespace driver
+
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_DRIVER_TOOLCHAIN_H
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
index 2430b5b924c32..c23f1f13361f7 100644
--- a/include/clang/Driver/Types.def
+++ b/include/clang/Driver/Types.def
@@ -46,6 +46,9 @@ TYPE("cl", CL, PP_C, "cl", "u")
TYPE("cuda-cpp-output", PP_CUDA, INVALID, "cui", "u")
TYPE("cuda", CUDA, PP_CUDA, "cu", "u")
TYPE("cuda", CUDA_DEVICE, PP_CUDA, "cu", "")
+TYPE("hip-cpp-output", PP_HIP, INVALID, "cui", "u")
+TYPE("hip", HIP, PP_HIP, "cu", "u")
+TYPE("hip", HIP_DEVICE, PP_HIP, "cu", "")
TYPE("objective-c-cpp-output", PP_ObjC, INVALID, "mi", "u")
TYPE("objc-cpp-output", PP_ObjC_Alias, INVALID, "mi", "u")
TYPE("objective-c", ObjC, PP_ObjC, "m", "u")
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
index 22a26ae46a0b9..5bc6668a0d1de 100644
--- a/include/clang/Driver/Types.h
+++ b/include/clang/Driver/Types.h
@@ -77,6 +77,9 @@ namespace types {
/// isCuda - Is this a CUDA input.
bool isCuda(ID Id);
+ /// isHIP - Is this a HIP input.
+ bool isHIP(ID Id);
+
/// isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
bool isObjC(ID Id);
diff --git a/include/clang/Driver/XRayArgs.h b/include/clang/Driver/XRayArgs.h
index e5b76162de8e2..c7ca945291758 100644
--- a/include/clang/Driver/XRayArgs.h
+++ b/include/clang/Driver/XRayArgs.h
@@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_DRIVER_XRAYARGS_H
#define LLVM_CLANG_DRIVER_XRAYARGS_H
+#include "clang/Basic/XRayInstr.h"
#include "clang/Driver/Types.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
@@ -21,16 +22,25 @@ class ToolChain;
class XRayArgs {
std::vector<std::string> AlwaysInstrumentFiles;
std::vector<std::string> NeverInstrumentFiles;
+ std::vector<std::string> AttrListFiles;
std::vector<std::string> ExtraDeps;
+ std::vector<std::string> Modes;
+ XRayInstrSet InstrumentationBundle;
bool XRayInstrument = false;
int InstructionThreshold = 200;
bool XRayAlwaysEmitCustomEvents = false;
+ bool XRayAlwaysEmitTypedEvents = false;
+ bool XRayRT = true;
public:
/// Parses the XRay arguments from an argument list.
XRayArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const;
+
+ bool needsXRayRt() const { return XRayInstrument && XRayRT; }
+ llvm::ArrayRef<std::string> modeList() const { return Modes; }
+ XRayInstrSet instrumentationBundle() const { return InstrumentationBundle; }
};
} // namespace driver
diff --git a/include/clang/Edit/Commit.h b/include/clang/Edit/Commit.h
index ac4bb471fe1c9..a574b8ef4cd24 100644
--- a/include/clang/Edit/Commit.h
+++ b/include/clang/Edit/Commit.h
@@ -1,4 +1,4 @@
-//===----- Commit.h - A unit of edits ---------------------------*- C++ -*-===//
+//===- Commit.h - A unit of edits -------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,17 +10,22 @@
#ifndef LLVM_CLANG_EDIT_COMMIT_H
#define LLVM_CLANG_EDIT_COMMIT_H
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Edit/FileOffset.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
namespace clang {
- class LangOptions;
- class PPConditionalDirectiveRecord;
+
+class LangOptions;
+class PPConditionalDirectiveRecord;
+class SourceManager;
namespace edit {
- class EditedSource;
+
+class EditedSource;
class Commit {
public:
@@ -48,9 +53,9 @@ private:
const SourceManager &SourceMgr;
const LangOptions &LangOpts;
const PPConditionalDirectiveRecord *PPRec;
- EditedSource *Editor;
+ EditedSource *Editor = nullptr;
- bool IsCommitable;
+ bool IsCommitable = true;
SmallVector<Edit, 8> CachedEdits;
llvm::BumpPtrAllocator StrAlloc;
@@ -59,21 +64,23 @@ public:
explicit Commit(EditedSource &Editor);
Commit(const SourceManager &SM, const LangOptions &LangOpts,
const PPConditionalDirectiveRecord *PPRec = nullptr)
- : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(nullptr),
- IsCommitable(true) { }
+ : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec) {}
bool isCommitable() const { return IsCommitable; }
bool insert(SourceLocation loc, StringRef text, bool afterToken = false,
bool beforePreviousInsertions = false);
+
bool insertAfterToken(SourceLocation loc, StringRef text,
bool beforePreviousInsertions = false) {
return insert(loc, text, /*afterToken=*/true, beforePreviousInsertions);
}
+
bool insertBefore(SourceLocation loc, StringRef text) {
return insert(loc, text, /*afterToken=*/false,
/*beforePreviousInsertions=*/true);
}
+
bool insertFromRange(SourceLocation loc, CharSourceRange range,
bool afterToken = false,
bool beforePreviousInsertions = false);
@@ -92,21 +99,26 @@ public:
return insertFromRange(loc, CharSourceRange::getTokenRange(TokenRange),
afterToken, beforePreviousInsertions);
}
+
bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) {
return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after);
}
+
bool remove(SourceRange TokenRange) {
return remove(CharSourceRange::getTokenRange(TokenRange));
}
+
bool replace(SourceRange TokenRange, StringRef text) {
return replace(CharSourceRange::getTokenRange(TokenRange), text);
}
+
bool replaceWithInner(SourceRange TokenRange, SourceRange TokenInnerRange) {
return replaceWithInner(CharSourceRange::getTokenRange(TokenRange),
CharSourceRange::getTokenRange(TokenInnerRange));
}
- typedef SmallVectorImpl<Edit>::const_iterator edit_iterator;
+ using edit_iterator = SmallVectorImpl<Edit>::const_iterator;
+
edit_iterator edit_begin() const { return CachedEdits.begin(); }
edit_iterator edit_end() const { return CachedEdits.end(); }
@@ -136,8 +148,8 @@ private:
SourceLocation *MacroEnd = nullptr) const;
};
-}
+} // namespace edit
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_EDIT_COMMIT_H
diff --git a/include/clang/Edit/EditedSource.h b/include/clang/Edit/EditedSource.h
index d95a0c2be805d..3d33688f5f737 100644
--- a/include/clang/Edit/EditedSource.h
+++ b/include/clang/Edit/EditedSource.h
@@ -1,4 +1,4 @@
-//===----- EditedSource.h - Collection of source edits ----------*- C++ -*-===//
+//===- EditedSource.h - Collection of source edits --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,21 +11,27 @@
#define LLVM_CLANG_EDIT_EDITEDSOURCE_H
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Edit/FileOffset.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
#include <map>
#include <tuple>
+#include <utility>
namespace clang {
- class LangOptions;
- class PPConditionalDirectiveRecord;
+
+class LangOptions;
+class PPConditionalDirectiveRecord;
+class SourceManager;
namespace edit {
- class Commit;
- class EditsReceiver;
+
+class Commit;
+class EditsReceiver;
class EditedSource {
const SourceManager &SourceMgr;
@@ -34,17 +40,19 @@ class EditedSource {
struct FileEdit {
StringRef Text;
- unsigned RemoveLen;
+ unsigned RemoveLen = 0;
- FileEdit() : RemoveLen(0) {}
+ FileEdit() = default;
};
- typedef std::map<FileOffset, FileEdit> FileEditsTy;
+ using FileEditsTy = std::map<FileOffset, FileEdit>;
+
FileEditsTy FileEdits;
struct MacroArgUse {
IdentifierInfo *Identifier;
SourceLocation ImmediateExpansionLoc;
+
// Location of argument use inside the top-level macro
SourceLocation UseLoc;
@@ -65,11 +73,11 @@ class EditedSource {
public:
EditedSource(const SourceManager &SM, const LangOptions &LangOpts,
const PPConditionalDirectiveRecord *PPRec = nullptr)
- : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), IdentTable(LangOpts),
- StrAlloc() { }
+ : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), IdentTable(LangOpts) {}
const SourceManager &getSourceManager() const { return SourceMgr; }
const LangOptions &getLangOpts() const { return LangOpts; }
+
const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const {
return PPRec;
}
@@ -103,8 +111,8 @@ private:
void finishedCommit();
};
-}
+} // namespace edit
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_EDIT_EDITEDSOURCE_H
diff --git a/include/clang/Edit/EditsReceiver.h b/include/clang/Edit/EditsReceiver.h
index 600ac28ea920e..1bebbeb873a71 100644
--- a/include/clang/Edit/EditsReceiver.h
+++ b/include/clang/Edit/EditsReceiver.h
@@ -1,4 +1,4 @@
-//===----- EditedSource.h - Collection of source edits ----------*- C++ -*-===//
+//===- EditedSource.h - Collection of source edits --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,25 +11,24 @@
#define LLVM_CLANG_EDIT_EDITSRECEIVER_H
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/StringRef.h"
namespace clang {
- class SourceLocation;
- class CharSourceRange;
-
namespace edit {
class EditsReceiver {
public:
- virtual ~EditsReceiver() { }
+ virtual ~EditsReceiver() = default;
virtual void insert(SourceLocation loc, StringRef text) = 0;
virtual void replace(CharSourceRange range, StringRef text) = 0;
- /// \brief By default it calls replace with an empty string.
+
+ /// By default it calls replace with an empty string.
virtual void remove(CharSourceRange range);
};
-}
-
-} // end namespace clang
+} // namespace edit
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_EDIT_EDITSRECEIVER_H
diff --git a/include/clang/Edit/FileOffset.h b/include/clang/Edit/FileOffset.h
index 0c1e72b84e51b..02c1b96b3331b 100644
--- a/include/clang/Edit/FileOffset.h
+++ b/include/clang/Edit/FileOffset.h
@@ -1,4 +1,4 @@
-//===----- FileOffset.h - Offset in a file ----------------------*- C++ -*-===//
+//===- FileOffset.h - Offset in a file --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,17 +11,18 @@
#define LLVM_CLANG_EDIT_FILEOFFSET_H
#include "clang/Basic/SourceLocation.h"
+#include <tuple>
namespace clang {
-
namespace edit {
class FileOffset {
FileID FID;
- unsigned Offs;
+ unsigned Offs = 0;
+
public:
- FileOffset() : Offs(0) { }
- FileOffset(FileID fid, unsigned offs) : FID(fid), Offs(offs) { }
+ FileOffset() = default;
+ FileOffset(FileID fid, unsigned offs) : FID(fid), Offs(offs) {}
bool isInvalid() const { return FID.isInvalid(); }
@@ -37,25 +38,29 @@ public:
friend bool operator==(FileOffset LHS, FileOffset RHS) {
return LHS.FID == RHS.FID && LHS.Offs == RHS.Offs;
}
+
friend bool operator!=(FileOffset LHS, FileOffset RHS) {
return !(LHS == RHS);
}
+
friend bool operator<(FileOffset LHS, FileOffset RHS) {
return std::tie(LHS.FID, LHS.Offs) < std::tie(RHS.FID, RHS.Offs);
}
+
friend bool operator>(FileOffset LHS, FileOffset RHS) {
return RHS < LHS;
}
+
friend bool operator>=(FileOffset LHS, FileOffset RHS) {
return !(LHS < RHS);
}
+
friend bool operator<=(FileOffset LHS, FileOffset RHS) {
return !(RHS < LHS);
}
};
-}
-
-} // end namespace clang
+} // namespace edit
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_EDIT_FILEOFFSET_H
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index d27d934f76798..85dda948c11f5 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -17,7 +17,9 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Tooling/Core/Replacement.h"
+#include "clang/Tooling/Inclusions/IncludeStyle.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Regex.h"
#include <system_error>
namespace clang {
@@ -41,27 +43,27 @@ public:
const std::error_category &getParseCategory();
std::error_code make_error_code(ParseError e);
-/// \brief The ``FormatStyle`` is used to configure the formatting to follow
+/// The ``FormatStyle`` is used to configure the formatting to follow
/// specific guidelines.
struct FormatStyle {
- /// \brief The extra indent or outdent of access modifiers, e.g. ``public:``.
+ /// The extra indent or outdent of access modifiers, e.g. ``public:``.
int AccessModifierOffset;
- /// \brief Different styles for aligning after open brackets.
+ /// Different styles for aligning after open brackets.
enum BracketAlignmentStyle {
- /// \brief Align parameters on the open bracket, e.g.:
+ /// Align parameters on the open bracket, e.g.:
/// \code
/// someLongFunction(argument1,
/// argument2);
/// \endcode
BAS_Align,
- /// \brief Don't align, instead use ``ContinuationIndentWidth``, e.g.:
+ /// Don't align, instead use ``ContinuationIndentWidth``, e.g.:
/// \code
/// someLongFunction(argument1,
/// argument2);
/// \endcode
BAS_DontAlign,
- /// \brief Always break after an open bracket, if the parameters don't fit
+ /// Always break after an open bracket, if the parameters don't fit
/// on a single line, e.g.:
/// \code
/// someLongFunction(
@@ -70,13 +72,13 @@ struct FormatStyle {
BAS_AlwaysBreak,
};
- /// \brief If ``true``, horizontally aligns arguments after an open bracket.
+ /// If ``true``, horizontally aligns arguments after an open bracket.
///
/// This applies to round brackets (parentheses), angle brackets and square
/// brackets.
BracketAlignmentStyle AlignAfterOpenBracket;
- /// \brief If ``true``, aligns consecutive assignments.
+ /// If ``true``, aligns consecutive assignments.
///
/// This will align the assignment operators of consecutive lines. This
/// will result in formattings like
@@ -87,7 +89,7 @@ struct FormatStyle {
/// \endcode
bool AlignConsecutiveAssignments;
- /// \brief If ``true``, aligns consecutive declarations.
+ /// If ``true``, aligns consecutive declarations.
///
/// This will align the declaration names of consecutive lines. This
/// will result in formattings like
@@ -98,9 +100,9 @@ struct FormatStyle {
/// \endcode
bool AlignConsecutiveDeclarations;
- /// \brief Different styles for aligning escaped newlines.
+ /// Different styles for aligning escaped newlines.
enum EscapedNewlineAlignmentStyle {
- /// \brief Don't align escaped newlines.
+ /// Don't align escaped newlines.
/// \code
/// #define A \
/// int aaaa; \
@@ -108,7 +110,7 @@ struct FormatStyle {
/// int dddddddddd;
/// \endcode
ENAS_DontAlign,
- /// \brief Align escaped newlines as far left as possible.
+ /// Align escaped newlines as far left as possible.
/// \code
/// true:
/// #define A \
@@ -119,7 +121,7 @@ struct FormatStyle {
/// false:
/// \endcode
ENAS_Left,
- /// \brief Align escaped newlines in the right-most column.
+ /// Align escaped newlines in the right-most column.
/// \code
/// #define A \
/// int aaaa; \
@@ -129,10 +131,10 @@ struct FormatStyle {
ENAS_Right,
};
- /// \brief Options for aligning backslashes in escaped newlines.
+ /// Options for aligning backslashes in escaped newlines.
EscapedNewlineAlignmentStyle AlignEscapedNewlines;
- /// \brief If ``true``, horizontally align operands of binary and ternary
+ /// If ``true``, horizontally align operands of binary and ternary
/// expressions.
///
/// Specifically, this aligns operands of a single expression that needs to be
@@ -143,7 +145,7 @@ struct FormatStyle {
/// \endcode
bool AlignOperands;
- /// \brief If ``true``, aligns trailing comments.
+ /// If ``true``, aligns trailing comments.
/// \code
/// true: false:
/// int a; // My comment a vs. int a; // My comment a
@@ -151,7 +153,7 @@ struct FormatStyle {
/// \endcode
bool AlignTrailingComments;
- /// \brief If the function declaration doesn't fit on a line,
+ /// If the function declaration doesn't fit on a line,
/// allow putting all parameters of a function declaration onto
/// the next line even if ``BinPackParameters`` is ``false``.
/// \code
@@ -168,12 +170,12 @@ struct FormatStyle {
/// \endcode
bool AllowAllParametersOfDeclarationOnNextLine;
- /// \brief Allows contracting simple braced statements to a single line.
+ /// Allows contracting simple braced statements to a single line.
///
/// E.g., this allows ``if (a) { return; }`` to be put on a single line.
bool AllowShortBlocksOnASingleLine;
- /// \brief If ``true``, short case labels will be contracted to a single line.
+ /// If ``true``, short case labels will be contracted to a single line.
/// \code
/// true: false:
/// switch (a) { vs. switch (a) {
@@ -186,12 +188,12 @@ struct FormatStyle {
/// \endcode
bool AllowShortCaseLabelsOnASingleLine;
- /// \brief Different styles for merging short functions containing at most one
+ /// Different styles for merging short functions containing at most one
/// statement.
enum ShortFunctionStyle {
- /// \brief Never merge functions into a single line.
+ /// Never merge functions into a single line.
SFS_None,
- /// \brief Only merge functions defined inside a class. Same as "inline",
+ /// Only merge functions defined inside a class. Same as "inline",
/// except it does not implies "empty": i.e. top level empty functions
/// are not merged either.
/// \code
@@ -205,7 +207,7 @@ struct FormatStyle {
/// }
/// \endcode
SFS_InlineOnly,
- /// \brief Only merge empty functions.
+ /// Only merge empty functions.
/// \code
/// void f() {}
/// void f2() {
@@ -213,7 +215,7 @@ struct FormatStyle {
/// }
/// \endcode
SFS_Empty,
- /// \brief Only merge functions defined inside a class. Implies "empty".
+ /// Only merge functions defined inside a class. Implies "empty".
/// \code
/// class Foo {
/// void f() { foo(); }
@@ -224,7 +226,7 @@ struct FormatStyle {
/// void f() {}
/// \endcode
SFS_Inline,
- /// \brief Merge all functions fitting on a single line.
+ /// Merge all functions fitting on a single line.
/// \code
/// class Foo {
/// void f() { foo(); }
@@ -234,18 +236,18 @@ struct FormatStyle {
SFS_All,
};
- /// \brief Dependent on the value, ``int f() { return 0; }`` can be put on a
+ /// Dependent on the value, ``int f() { return 0; }`` can be put on a
/// single line.
ShortFunctionStyle AllowShortFunctionsOnASingleLine;
- /// \brief If ``true``, ``if (a) return;`` can be put on a single line.
+ /// If ``true``, ``if (a) return;`` can be put on a single line.
bool AllowShortIfStatementsOnASingleLine;
- /// \brief If ``true``, ``while (true) continue;`` can be put on a single
+ /// If ``true``, ``while (true) continue;`` can be put on a single
/// line.
bool AllowShortLoopsOnASingleLine;
- /// \brief Different ways to break after the function definition return type.
+ /// Different ways to break after the function definition return type.
/// This option is **deprecated** and is retained for backwards compatibility.
enum DefinitionReturnTypeBreakingStyle {
/// Break after return type automatically.
@@ -257,7 +259,7 @@ struct FormatStyle {
DRTBS_TopLevel,
};
- /// \brief Different ways to break after the function definition or
+ /// Different ways to break after the function definition or
/// declaration return type.
enum ReturnTypeBreakingStyle {
/// Break after return type automatically.
@@ -328,14 +330,14 @@ struct FormatStyle {
RTBS_TopLevelDefinitions,
};
- /// \brief The function definition return type breaking style to use. This
+ /// The function definition return type breaking style to use. This
/// option is **deprecated** and is retained for backwards compatibility.
DefinitionReturnTypeBreakingStyle AlwaysBreakAfterDefinitionReturnType;
- /// \brief The function declaration return type breaking style to use.
+ /// The function declaration return type breaking style to use.
ReturnTypeBreakingStyle AlwaysBreakAfterReturnType;
- /// \brief If ``true``, always break before multiline string literals.
+ /// If ``true``, always break before multiline string literals.
///
/// This flag is mean to make cases where there are multiple multiline strings
/// in a file look more consistent. Thus, it will only take effect if wrapping
@@ -349,16 +351,46 @@ struct FormatStyle {
/// \endcode
bool AlwaysBreakBeforeMultilineStrings;
- /// \brief If ``true``, always break after the ``template<...>`` of a template
- /// declaration.
- /// \code
- /// true: false:
- /// template <typename T> vs. template <typename T> class C {};
- /// class C {};
- /// \endcode
- bool AlwaysBreakTemplateDeclarations;
+ /// Different ways to break after the template declaration.
+ enum BreakTemplateDeclarationsStyle {
+ /// Do not force break before declaration.
+ /// ``PenaltyBreakTemplateDeclaration`` is taken into account.
+ /// \code
+ /// template <typename T> T foo() {
+ /// }
+ /// template <typename T> T foo(int aaaaaaaaaaaaaaaaaaaaa,
+ /// int bbbbbbbbbbbbbbbbbbbbb) {
+ /// }
+ /// \endcode
+ BTDS_No,
+ /// Force break after template declaration only when the following
+ /// declaration spans multiple lines.
+ /// \code
+ /// template <typename T> T foo() {
+ /// }
+ /// template <typename T>
+ /// T foo(int aaaaaaaaaaaaaaaaaaaaa,
+ /// int bbbbbbbbbbbbbbbbbbbbb) {
+ /// }
+ /// \endcode
+ BTDS_MultiLine,
+ /// Always break after template declaration.
+ /// \code
+ /// template <typename T>
+ /// T foo() {
+ /// }
+ /// template <typename T>
+ /// T foo(int aaaaaaaaaaaaaaaaaaaaa,
+ /// int bbbbbbbbbbbbbbbbbbbbb) {
+ /// }
+ /// \endcode
+ BTDS_Yes
+ };
+
+ /// The template declaration breaking style to use.
+ BreakTemplateDeclarationsStyle AlwaysBreakTemplateDeclarations;
- /// \brief If ``false``, a function call's arguments will either be all on the
+ /// If ``false``, a function call's arguments will either be all on the
/// same line or will have one line each.
/// \code
/// true:
@@ -376,7 +408,7 @@ struct FormatStyle {
/// \endcode
bool BinPackArguments;
- /// \brief If ``false``, a function declaration's or function definition's
+ /// If ``false``, a function declaration's or function definition's
/// parameters will either all be on the same line or will have one line each.
/// \code
/// true:
@@ -390,7 +422,18 @@ struct FormatStyle {
/// \endcode
bool BinPackParameters;
- /// \brief The style of breaking before or after binary operators.
+ /// The style of wrapping parameters on the same line (bin-packed) or
+ /// on one line each.
+ enum BinPackStyle {
+ /// Automatically determine parameter bin-packing behavior.
+ BPS_Auto,
+ /// Always bin-pack parameters.
+ BPS_Always,
+ /// Never bin-pack parameters.
+ BPS_Never,
+ };
+
+ /// The style of breaking before or after binary operators.
enum BinaryOperatorStyle {
/// Break after operators.
/// \code
@@ -430,10 +473,10 @@ struct FormatStyle {
BOS_All,
};
- /// \brief The way to wrap binary operators.
+ /// The way to wrap binary operators.
BinaryOperatorStyle BreakBeforeBinaryOperators;
- /// \brief Different ways to attach braces to their surrounding context.
+ /// Different ways to attach braces to their surrounding context.
enum BraceBreakingStyle {
/// Always attach braces to surrounding context.
/// \code
@@ -568,10 +611,10 @@ struct FormatStyle {
BS_Custom
};
- /// \brief The brace breaking style to use.
+ /// The brace breaking style to use.
BraceBreakingStyle BreakBeforeBraces;
- /// \brief Precise control over the wrapping of braces.
+ /// Precise control over the wrapping of braces.
/// \code
/// # Should be declared this way:
/// BreakBeforeBraces: Custom
@@ -579,7 +622,7 @@ struct FormatStyle {
/// AfterClass: true
/// \endcode
struct BraceWrappingFlags {
- /// \brief Wrap class definitions.
+ /// Wrap class definitions.
/// \code
/// true:
/// class foo {};
@@ -589,7 +632,7 @@ struct FormatStyle {
/// {};
/// \endcode
bool AfterClass;
- /// \brief Wrap control statements (``if``/``for``/``while``/``switch``/..).
+ /// Wrap control statements (``if``/``for``/``while``/``switch``/..).
/// \code
/// true:
/// if (foo())
@@ -607,7 +650,7 @@ struct FormatStyle {
/// }
/// \endcode
bool AfterControlStatement;
- /// \brief Wrap enum definitions.
+ /// Wrap enum definitions.
/// \code
/// true:
/// enum X : int
@@ -619,7 +662,7 @@ struct FormatStyle {
/// enum X : int { B };
/// \endcode
bool AfterEnum;
- /// \brief Wrap function definitions.
+ /// Wrap function definitions.
/// \code
/// true:
/// void foo()
@@ -635,7 +678,7 @@ struct FormatStyle {
/// }
/// \endcode
bool AfterFunction;
- /// \brief Wrap namespace definitions.
+ /// Wrap namespace definitions.
/// \code
/// true:
/// namespace
@@ -651,9 +694,11 @@ struct FormatStyle {
/// }
/// \endcode
bool AfterNamespace;
- /// \brief Wrap ObjC definitions (``@autoreleasepool``, interfaces, ..).
+ /// Wrap ObjC definitions (interfaces, implementations...).
+ /// \note @autoreleasepool and @synchronized blocks are wrapped
+ /// according to `AfterControlStatement` flag.
bool AfterObjCDeclaration;
- /// \brief Wrap struct definitions.
+ /// Wrap struct definitions.
/// \code
/// true:
/// struct foo
@@ -667,7 +712,7 @@ struct FormatStyle {
/// };
/// \endcode
bool AfterStruct;
- /// \brief Wrap union definitions.
+ /// Wrap union definitions.
/// \code
/// true:
/// union foo
@@ -681,7 +726,7 @@ struct FormatStyle {
/// }
/// \endcode
bool AfterUnion;
- /// \brief Wrap extern blocks.
+ /// Wrap extern blocks.
/// \code
/// true:
/// extern "C"
@@ -695,7 +740,7 @@ struct FormatStyle {
/// }
/// \endcode
bool AfterExternBlock;
- /// \brief Wrap before ``catch``.
+ /// Wrap before ``catch``.
/// \code
/// true:
/// try {
@@ -711,7 +756,7 @@ struct FormatStyle {
/// }
/// \endcode
bool BeforeCatch;
- /// \brief Wrap before ``else``.
+ /// Wrap before ``else``.
/// \code
/// true:
/// if (foo()) {
@@ -725,9 +770,9 @@ struct FormatStyle {
/// }
/// \endcode
bool BeforeElse;
- /// \brief Indent the wrapped braces themselves.
+ /// Indent the wrapped braces themselves.
bool IndentBraces;
- /// \brief If ``false``, empty function body can be put on a single line.
+ /// If ``false``, empty function body can be put on a single line.
/// This option is used only if the opening brace of the function has
/// already been wrapped, i.e. the `AfterFunction` brace wrapping mode is
/// set, and the function could/should not be put on a single line (as per
@@ -739,7 +784,7 @@ struct FormatStyle {
/// \endcode
///
bool SplitEmptyFunction;
- /// \brief If ``false``, empty record (e.g. class, struct or union) body
+ /// If ``false``, empty record (e.g. class, struct or union) body
/// can be put on a single line. This option is used only if the opening
/// brace of the record has already been wrapped, i.e. the `AfterClass`
/// (for classes) brace wrapping mode is set.
@@ -750,7 +795,7 @@ struct FormatStyle {
/// \endcode
///
bool SplitEmptyRecord;
- /// \brief If ``false``, empty namespace body can be put on a single line.
+ /// If ``false``, empty namespace body can be put on a single line.
/// This option is used only if the opening brace of the namespace has
/// already been wrapped, i.e. the `AfterNamespace` brace wrapping mode is
/// set.
@@ -763,7 +808,7 @@ struct FormatStyle {
bool SplitEmptyNamespace;
};
- /// \brief Control of individual brace wrapping cases.
+ /// Control of individual brace wrapping cases.
///
/// If ``BreakBeforeBraces`` is set to ``BS_Custom``, use this to specify how
/// each individual brace case should be handled. Otherwise, this is ignored.
@@ -777,7 +822,7 @@ struct FormatStyle {
/// \endcode
BraceWrappingFlags BraceWrapping;
- /// \brief If ``true``, ternary operators will be placed after line breaks.
+ /// If ``true``, ternary operators will be placed after line breaks.
/// \code
/// true:
/// veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription
@@ -791,36 +836,36 @@ struct FormatStyle {
/// \endcode
bool BreakBeforeTernaryOperators;
- /// \brief Different ways to break initializers.
+ /// Different ways to break initializers.
enum BreakConstructorInitializersStyle {
/// Break constructor initializers before the colon and after the commas.
/// \code
- /// Constructor()
- /// : initializer1(),
- /// initializer2()
+ /// Constructor()
+ /// : initializer1(),
+ /// initializer2()
/// \endcode
BCIS_BeforeColon,
/// Break constructor initializers before the colon and commas, and align
/// the commas with the colon.
/// \code
- /// Constructor()
- /// : initializer1()
- /// , initializer2()
+ /// Constructor()
+ /// : initializer1()
+ /// , initializer2()
/// \endcode
BCIS_BeforeComma,
/// Break constructor initializers after the colon and commas.
/// \code
- /// Constructor() :
- /// initializer1(),
- /// initializer2()
+ /// Constructor() :
+ /// initializer1(),
+ /// initializer2()
/// \endcode
BCIS_AfterColon
};
- /// \brief The constructor initializers style to use.
+ /// The constructor initializers style to use.
BreakConstructorInitializersStyle BreakConstructorInitializers;
- /// \brief Break after each annotation on a field in Java files.
+ /// Break after each annotation on a field in Java files.
/// \code{.java}
/// true: false:
/// @Partial vs. @Partial @Mock DataLoad loader;
@@ -829,17 +874,17 @@ struct FormatStyle {
/// \endcode
bool BreakAfterJavaFieldAnnotations;
- /// \brief Allow breaking string literals when formatting.
+ /// Allow breaking string literals when formatting.
bool BreakStringLiterals;
- /// \brief The column limit.
+ /// The column limit.
///
/// A column limit of ``0`` means that there is no column limit. In this case,
/// clang-format will respect the input's line breaking decisions within
/// statements unless they contradict other rules.
unsigned ColumnLimit;
- /// \brief A regular expression that describes comments with special meaning,
+ /// A regular expression that describes comments with special meaning,
/// which should not be split into lines or otherwise changed.
/// \code
/// // CommentPragmas: '^ FOOBAR pragma:'
@@ -848,18 +893,39 @@ struct FormatStyle {
/// \endcode
std::string CommentPragmas;
- /// \brief If ``true``, in the class inheritance expression clang-format will
- /// break before ``:`` and ``,`` if there is multiple inheritance.
- /// \code
- /// true: false:
- /// class MyClass vs. class MyClass : public X, public Y {
- /// : public X };
- /// , public Y {
- /// };
- /// \endcode
- bool BreakBeforeInheritanceComma;
+ /// Different ways to break inheritance list.
+ enum BreakInheritanceListStyle {
+ /// Break inheritance list before the colon and after the commas.
+ /// \code
+ /// class Foo
+ /// : Base1,
+ /// Base2
+ /// {};
+ /// \endcode
+ BILS_BeforeColon,
+ /// Break inheritance list before the colon and commas, and align
+ /// the commas with the colon.
+ /// \code
+ /// class Foo
+ /// : Base1
+ /// , Base2
+ /// {};
+ /// \endcode
+ BILS_BeforeComma,
+ /// Break inheritance list after the colon and commas.
+ /// \code
+ /// class Foo :
+ /// Base1,
+ /// Base2
+ /// {};
+ /// \endcode
+ BILS_AfterColon
+ };
+
+ /// The inheritance list style to use.
+ BreakInheritanceListStyle BreakInheritanceList;
- /// \brief If ``true``, consecutive namespace declarations will be on the same
+ /// If ``true``, consecutive namespace declarations will be on the same
/// line. If ``false``, each namespace is declared on a new line.
/// \code
/// true:
@@ -882,7 +948,7 @@ struct FormatStyle {
/// \endcode
bool CompactNamespaces;
- /// \brief If the constructor initializers don't fit on a line, put each
+ /// If the constructor initializers don't fit on a line, put each
/// initializer on its own line.
/// \code
/// true:
@@ -900,11 +966,11 @@ struct FormatStyle {
/// \endcode
bool ConstructorInitializerAllOnOneLineOrOnePerLine;
- /// \brief The number of characters to use for indentation of constructor
- /// initializer lists.
+ /// The number of characters to use for indentation of constructor
+ /// initializer lists as well as inheritance lists.
unsigned ConstructorInitializerIndentWidth;
- /// \brief Indent width for line continuations.
+ /// Indent width for line continuations.
/// \code
/// ContinuationIndentWidth: 2
///
@@ -914,7 +980,7 @@ struct FormatStyle {
/// \endcode
unsigned ContinuationIndentWidth;
- /// \brief If ``true``, format braced lists as best suited for C++11 braced
+ /// If ``true``, format braced lists as best suited for C++11 braced
/// lists.
///
/// Important differences:
@@ -936,17 +1002,17 @@ struct FormatStyle {
/// \endcode
bool Cpp11BracedListStyle;
- /// \brief If ``true``, analyze the formatted file for the most common
+ /// If ``true``, analyze the formatted file for the most common
/// alignment of ``&`` and ``*``.
/// Pointer and reference alignment styles are going to be updated according
/// to the preferences found in the file.
/// ``PointerAlignment`` is then used only as fallback.
bool DerivePointerAlignment;
- /// \brief Disables formatting completely.
+ /// Disables formatting completely.
bool DisableFormat;
- /// \brief If ``true``, clang-format detects whether function calls and
+ /// If ``true``, clang-format detects whether function calls and
/// definitions are formatted with one parameter per line.
///
/// Each call can be bin-packed, one-per-line or inconclusive. If it is
@@ -958,7 +1024,7 @@ struct FormatStyle {
/// not use this in config files, etc. Use at your own risk.
bool ExperimentalAutoDetectBinPacking;
- /// \brief If ``true``, clang-format adds missing namespace end comments and
+ /// If ``true``, clang-format adds missing namespace end comments and
/// fixes invalid existing ones.
/// \code
/// true: false:
@@ -968,7 +1034,7 @@ struct FormatStyle {
/// \endcode
bool FixNamespaceComments;
- /// \brief A vector of macros that should be interpreted as foreach loops
+ /// A vector of macros that should be interpreted as foreach loops
/// instead of as function calls.
///
/// These are expected to be macros of the form:
@@ -985,93 +1051,9 @@ struct FormatStyle {
/// For example: BOOST_FOREACH.
std::vector<std::string> ForEachMacros;
- /// \brief Styles for sorting multiple ``#include`` blocks.
- enum IncludeBlocksStyle {
- /// \brief Sort each ``#include`` block separately.
- /// \code
- /// #include "b.h" into #include "b.h"
- ///
- /// #include <lib/main.h> #include "a.h"
- /// #include "a.h" #include <lib/main.h>
- /// \endcode
- IBS_Preserve,
- /// \brief Merge multiple ``#include`` blocks together and sort as one.
- /// \code
- /// #include "b.h" into #include "a.h"
- /// #include "b.h"
- /// #include <lib/main.h> #include <lib/main.h>
- /// #include "a.h"
- /// \endcode
- IBS_Merge,
- /// \brief Merge multiple ``#include`` blocks together and sort as one.
- /// Then split into groups based on category priority. See
- /// ``IncludeCategories``.
- /// \code
- /// #include "b.h" into #include "a.h"
- /// #include "b.h"
- /// #include <lib/main.h>
- /// #include "a.h" #include <lib/main.h>
- /// \endcode
- IBS_Regroup,
- };
-
- /// \brief Dependent on the value, multiple ``#include`` blocks can be sorted
- /// as one and divided based on category.
- IncludeBlocksStyle IncludeBlocks;
-
- /// \brief See documentation of ``IncludeCategories``.
- struct IncludeCategory {
- /// \brief The regular expression that this category matches.
- std::string Regex;
- /// \brief The priority to assign to this category.
- int Priority;
- bool operator==(const IncludeCategory &Other) const {
- return Regex == Other.Regex && Priority == Other.Priority;
- }
- };
+ tooling::IncludeStyle IncludeStyle;
- /// \brief Regular expressions denoting the different ``#include`` categories
- /// used for ordering ``#includes``.
- ///
- /// These regular expressions are matched against the filename of an include
- /// (including the <> or "") in order. The value belonging to the first
- /// matching regular expression is assigned and ``#includes`` are sorted first
- /// according to increasing category number and then alphabetically within
- /// each category.
- ///
- /// If none of the regular expressions match, INT_MAX is assigned as
- /// category. The main header for a source file automatically gets category 0.
- /// so that it is generally kept at the beginning of the ``#includes``
- /// (http://llvm.org/docs/CodingStandards.html#include-style). However, you
- /// can also assign negative priorities if you have certain headers that
- /// always need to be first.
- ///
- /// To configure this in the .clang-format file, use:
- /// \code{.yaml}
- /// IncludeCategories:
- /// - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
- /// Priority: 2
- /// - Regex: '^(<|"(gtest|gmock|isl|json)/)'
- /// Priority: 3
- /// - Regex: '.*'
- /// Priority: 1
- /// \endcode
- std::vector<IncludeCategory> IncludeCategories;
-
- /// \brief Specify a regular expression of suffixes that are allowed in the
- /// file-to-main-include mapping.
- ///
- /// When guessing whether a #include is the "main" include (to assign
- /// category 0, see above), use this regex of allowed suffixes to the header
- /// stem. A partial match is done, so that:
- /// - "" means "arbitrary suffix"
- /// - "$" means "no suffix"
- ///
- /// For example, if configured to "(_test)?$", then a header a.h would be seen
- /// as the "main" include in both a.cc and a_test.cc.
- std::string IncludeIsMainRegex;
-
- /// \brief Indent case labels one level from the switch statement.
+ /// Indent case labels one level from the switch statement.
///
/// When ``false``, use the same indentation level as for the switch statement.
/// Switch statement body is always indented one level more than case labels.
@@ -1087,7 +1069,7 @@ struct FormatStyle {
/// \endcode
bool IndentCaseLabels;
- /// \brief Options for indenting preprocessor directives.
+ /// Options for indenting preprocessor directives.
enum PPDirectiveIndentStyle {
/// Does not indent any directives.
/// \code
@@ -1109,10 +1091,10 @@ struct FormatStyle {
PPDIS_AfterHash
};
- /// \brief The preprocessor directive indenting style to use.
+ /// The preprocessor directive indenting style to use.
PPDirectiveIndentStyle IndentPPDirectives;
- /// \brief The number of columns to use for indentation.
+ /// The number of columns to use for indentation.
/// \code
/// IndentWidth: 3
///
@@ -1125,7 +1107,7 @@ struct FormatStyle {
/// \endcode
unsigned IndentWidth;
- /// \brief Indent if a function definition or declaration is wrapped after the
+ /// Indent if a function definition or declaration is wrapped after the
/// type.
/// \code
/// true:
@@ -1138,7 +1120,7 @@ struct FormatStyle {
/// \endcode
bool IndentWrappedFunctionNames;
- /// \brief Quotation styles for JavaScript strings. Does not affect template
+ /// Quotation styles for JavaScript strings. Does not affect template
/// strings.
enum JavaScriptQuoteStyle {
/// Leave string quotes as they are.
@@ -1161,10 +1143,10 @@ struct FormatStyle {
JSQS_Double
};
- /// \brief The JavaScriptQuoteStyle to use for JavaScript strings.
+ /// The JavaScriptQuoteStyle to use for JavaScript strings.
JavaScriptQuoteStyle JavaScriptQuotes;
- /// \brief Whether to wrap JavaScript import/export statements.
+ /// Whether to wrap JavaScript import/export statements.
/// \code{.js}
/// true:
/// import {
@@ -1178,7 +1160,7 @@ struct FormatStyle {
/// \endcode
bool JavaScriptWrapImports;
- /// \brief If true, the empty line at the start of blocks is kept.
+ /// If true, the empty line at the start of blocks is kept.
/// \code
/// true: false:
/// if (foo) { vs. if (foo) {
@@ -1188,7 +1170,7 @@ struct FormatStyle {
/// \endcode
bool KeepEmptyLinesAtTheStartOfBlocks;
- /// \brief Supported languages.
+ /// Supported languages.
///
/// When stored in a configuration file, specifies the language, that the
/// configuration targets. When passed to the ``reformat()`` function, enables
@@ -1215,10 +1197,10 @@ struct FormatStyle {
};
bool isCpp() const { return Language == LK_Cpp || Language == LK_ObjC; }
- /// \brief Language, this format style is targeted at.
+ /// Language, this format style is targeted at.
LanguageKind Language;
- /// \brief A regular expression matching macros that start a block.
+ /// A regular expression matching macros that start a block.
/// \code
/// # With:
/// MacroBlockBegin: "^NS_MAP_BEGIN|\
@@ -1246,10 +1228,10 @@ struct FormatStyle {
/// \endcode
std::string MacroBlockBegin;
- /// \brief A regular expression matching macros that end a block.
+ /// A regular expression matching macros that end a block.
std::string MacroBlockEnd;
- /// \brief The maximum number of consecutive empty lines to keep.
+ /// The maximum number of consecutive empty lines to keep.
/// \code
/// MaxEmptyLinesToKeep: 1 vs. MaxEmptyLinesToKeep: 0
/// int f() { int f() {
@@ -1262,7 +1244,7 @@ struct FormatStyle {
/// \endcode
unsigned MaxEmptyLinesToKeep;
- /// \brief Different ways to indent namespace contents.
+ /// Different ways to indent namespace contents.
enum NamespaceIndentationKind {
/// Don't indent in namespaces.
/// \code
@@ -1296,10 +1278,42 @@ struct FormatStyle {
NI_All
};
- /// \brief The indentation used for namespaces.
+ /// The indentation used for namespaces.
NamespaceIndentationKind NamespaceIndentation;
- /// \brief The number of characters to use for indentation of ObjC blocks.
+ /// Controls bin-packing Objective-C protocol conformance list
+ /// items into as few lines as possible when they go over ``ColumnLimit``.
+ ///
+ /// If ``Auto`` (the default), delegates to the value in
+ /// ``BinPackParameters``. If that is ``true``, bin-packs Objective-C
+ /// protocol conformance list items into as few lines as possible
+ /// whenever they go over ``ColumnLimit``.
+ ///
+ /// If ``Always``, always bin-packs Objective-C protocol conformance
+ /// list items into as few lines as possible whenever they go over
+ /// ``ColumnLimit``.
+ ///
+ /// If ``Never``, lays out Objective-C protocol conformance list items
+ /// onto individual lines whenever they go over ``ColumnLimit``.
+ ///
+ /// \code{.objc}
+ /// Always (or Auto, if BinPackParameters=true):
+ /// @interface ccccccccccccc () <
+ /// ccccccccccccc, ccccccccccccc,
+ /// ccccccccccccc, ccccccccccccc> {
+ /// }
+ ///
+ /// Never (or Auto, if BinPackParameters=false):
+ /// @interface ddddddddddddd () <
+ /// ddddddddddddd,
+ /// ddddddddddddd,
+ /// ddddddddddddd,
+ /// ddddddddddddd> {
+ /// }
+ /// \endcode
+ BinPackStyle ObjCBinPackProtocolList;
+
+ /// The number of characters to use for indentation of ObjC blocks.
/// \code{.objc}
/// ObjCBlockIndentWidth: 4
///
@@ -1309,37 +1323,40 @@ struct FormatStyle {
/// \endcode
unsigned ObjCBlockIndentWidth;
- /// \brief Add a space after ``@property`` in Objective-C, i.e. use
+ /// Add a space after ``@property`` in Objective-C, i.e. use
/// ``@property (readonly)`` instead of ``@property(readonly)``.
bool ObjCSpaceAfterProperty;
- /// \brief Add a space in front of an Objective-C protocol list, i.e. use
+ /// Add a space in front of an Objective-C protocol list, i.e. use
/// ``Foo <Protocol>`` instead of ``Foo<Protocol>``.
bool ObjCSpaceBeforeProtocolList;
- /// \brief The penalty for breaking around an assignment operator.
+ /// The penalty for breaking around an assignment operator.
unsigned PenaltyBreakAssignment;
- /// \brief The penalty for breaking a function call after ``call(``.
+ /// The penalty for breaking a function call after ``call(``.
unsigned PenaltyBreakBeforeFirstCallParameter;
- /// \brief The penalty for each line break introduced inside a comment.
+ /// The penalty for each line break introduced inside a comment.
unsigned PenaltyBreakComment;
- /// \brief The penalty for breaking before the first ``<<``.
+ /// The penalty for breaking before the first ``<<``.
unsigned PenaltyBreakFirstLessLess;
- /// \brief The penalty for each line break introduced inside a string literal.
+ /// The penalty for each line break introduced inside a string literal.
unsigned PenaltyBreakString;
- /// \brief The penalty for each character outside of the column limit.
+ /// The penalty for breaking after template declaration.
+ unsigned PenaltyBreakTemplateDeclaration;
+
+ /// The penalty for each character outside of the column limit.
unsigned PenaltyExcessCharacter;
- /// \brief Penalty for putting the return type of a function onto its own
+ /// Penalty for putting the return type of a function onto its own
/// line.
unsigned PenaltyReturnTypeOnItsOwnLine;
- /// \brief The ``&`` and ``*`` alignment style.
+ /// The ``&`` and ``*`` alignment style.
enum PointerAlignmentStyle {
/// Align pointer to the left.
/// \code
@@ -1358,45 +1375,69 @@ struct FormatStyle {
PAS_Middle
};
- /// \brief Pointer and reference alignment style.
+ /// Pointer and reference alignment style.
PointerAlignmentStyle PointerAlignment;
/// See documentation of ``RawStringFormats``.
struct RawStringFormat {
- /// \brief The delimiter that this raw string format matches.
- std::string Delimiter;
- /// \brief The language of this raw string.
+ /// The language of this raw string.
LanguageKind Language;
- /// \brief The style name on which this raw string format is based on.
+ /// A list of raw string delimiters that match this language.
+ std::vector<std::string> Delimiters;
+ /// A list of enclosing function names that match this language.
+ std::vector<std::string> EnclosingFunctions;
+ /// The canonical delimiter for this language.
+ std::string CanonicalDelimiter;
+ /// The style name on which this raw string format is based on.
/// If not specified, the raw string format is based on the style that this
/// format is based on.
std::string BasedOnStyle;
bool operator==(const RawStringFormat &Other) const {
- return Delimiter == Other.Delimiter && Language == Other.Language &&
+ return Language == Other.Language && Delimiters == Other.Delimiters &&
+ EnclosingFunctions == Other.EnclosingFunctions &&
+ CanonicalDelimiter == Other.CanonicalDelimiter &&
BasedOnStyle == Other.BasedOnStyle;
}
};
- /// \brief Raw string delimiters denoting that the raw string contents are
- /// code in a particular language and can be reformatted.
+ /// Defines hints for detecting supported languages code blocks in raw
+ /// strings.
+ ///
+ /// A raw string with a matching delimiter or a matching enclosing function
+ /// name will be reformatted assuming the specified language based on the
+ /// style for that language defined in the .clang-format file. If no style has
+ /// been defined in the .clang-format file for the specific language, a
+ /// predefined style given by 'BasedOnStyle' is used. If 'BasedOnStyle' is not
+ /// found, the formatting is based on llvm style. A matching delimiter takes
+ /// precedence over a matching enclosing function name for determining the
+ /// language of the raw string contents.
///
- /// A raw string with a matching delimiter will be reformatted assuming the
- /// specified language based on a predefined style given by 'BasedOnStyle'.
- /// If 'BasedOnStyle' is not found, the formatting is based on llvm style.
+ /// If a canonical delimiter is specified, occurrences of other delimiters for
+ /// the same language will be updated to the canonical if possible.
+ ///
+ /// There should be at most one specification per language and each delimiter
+ /// and enclosing function should not occur in multiple specifications.
///
/// To configure this in the .clang-format file, use:
/// \code{.yaml}
/// RawStringFormats:
- /// - Delimiter: 'pb'
- /// Language: TextProto
- /// BasedOnStyle: llvm
- /// - Delimiter: 'proto'
- /// Language: TextProto
- /// BasedOnStyle: google
+ /// - Language: TextProto
+ /// Delimiters:
+ /// - 'pb'
+ /// - 'proto'
+ /// EnclosingFunctions:
+ /// - 'PARSE_TEXT_PROTO'
+ /// BasedOnStyle: google
+ /// - Language: Cpp
+ /// Delimiters:
+ /// - 'cc'
+ /// - 'cpp'
+ /// BasedOnStyle: llvm
+ /// CanonicalDelimiter: 'cc'
/// \endcode
std::vector<RawStringFormat> RawStringFormats;
- /// \brief If ``true``, clang-format will attempt to re-flow comments.
+ /// If ``true``, clang-format will attempt to re-flow comments.
/// \code
/// false:
/// // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information
@@ -1410,7 +1451,7 @@ struct FormatStyle {
/// \endcode
bool ReflowComments;
- /// \brief If ``true``, clang-format will sort ``#includes``.
+ /// If ``true``, clang-format will sort ``#includes``.
/// \code
/// false: true:
/// #include "b.h" vs. #include "a.h"
@@ -1418,7 +1459,7 @@ struct FormatStyle {
/// \endcode
bool SortIncludes;
- /// \brief If ``true``, clang-format will sort using declarations.
+ /// If ``true``, clang-format will sort using declarations.
///
/// The order of using declarations is defined as follows:
/// Split the strings by "::" and discard any initial empty strings. The last
@@ -1434,21 +1475,21 @@ struct FormatStyle {
/// \endcode
bool SortUsingDeclarations;
- /// \brief If ``true``, a space is inserted after C style casts.
+ /// If ``true``, a space is inserted after C style casts.
/// \code
/// true: false:
- /// (int)i; vs. (int) i;
+ /// (int) i; vs. (int)i;
/// \endcode
bool SpaceAfterCStyleCast;
- /// \brief If \c true, a space will be inserted after the 'template' keyword.
+ /// If \c true, a space will be inserted after the 'template' keyword.
/// \code
/// true: false:
/// template <int> void foo(); vs. template<int> void foo();
/// \endcode
bool SpaceAfterTemplateKeyword;
- /// \brief If ``false``, spaces will be removed before assignment operators.
+ /// If ``false``, spaces will be removed before assignment operators.
/// \code
/// true: false:
/// int a = 5; vs. int a=5;
@@ -1456,7 +1497,33 @@ struct FormatStyle {
/// \endcode
bool SpaceBeforeAssignmentOperators;
- /// \brief Different ways to put a space before opening parentheses.
+ /// If ``true``, a space will be inserted before a C++11 braced list
+ /// used to initialize an object (after the preceding identifier or type).
+ /// \code
+ /// true: false:
+ /// Foo foo { bar }; vs. Foo foo{ bar };
+ /// Foo {}; Foo{};
+ /// vector<int> { 1, 2, 3 }; vector<int>{ 1, 2, 3 };
+ /// new int[3] { 1, 2, 3 }; new int[3]{ 1, 2, 3 };
+ /// \endcode
+ bool SpaceBeforeCpp11BracedList;
+
+ /// If ``false``, spaces will be removed before constructor initializer
+ /// colon.
+ /// \code
+ /// true: false:
+ /// Foo::Foo() : a(a) {} Foo::Foo(): a(a) {}
+ /// \endcode
+ bool SpaceBeforeCtorInitializerColon;
+
+ /// If ``false``, spaces will be removed before inheritance colon.
+ /// \code
+ /// true: false:
+ /// class Foo : Bar {} vs. class Foo: Bar {}
+ /// \endcode
+ bool SpaceBeforeInheritanceColon;
+
+ /// Different ways to put a space before opening parentheses.
enum SpaceBeforeParensOptions {
/// Never put a space before opening parentheses.
/// \code
@@ -1491,10 +1558,18 @@ struct FormatStyle {
SBPO_Always
};
- /// \brief Defines in which cases to put a space before opening parentheses.
+ /// Defines in which cases to put a space before opening parentheses.
SpaceBeforeParensOptions SpaceBeforeParens;
- /// \brief If ``true``, spaces may be inserted into ``()``.
+ /// If ``false``, spaces will be removed before range-based for loop
+ /// colon.
+ /// \code
+ /// true: false:
+ /// for (auto v : values) {} vs. for(auto v: values) {}
+ /// \endcode
+ bool SpaceBeforeRangeBasedForLoopColon;
+
+ /// If ``true``, spaces may be inserted into ``()``.
/// \code
/// true: false:
/// void f( ) { vs. void f() {
@@ -1506,7 +1581,7 @@ struct FormatStyle {
/// \endcode
bool SpaceInEmptyParentheses;
- /// \brief The number of spaces before trailing line comments
+ /// The number of spaces before trailing line comments
/// (``//`` - comments).
///
/// This does not affect trailing block comments (``/*`` - comments) as
@@ -1522,7 +1597,7 @@ struct FormatStyle {
/// \endcode
unsigned SpacesBeforeTrailingComments;
- /// \brief If ``true``, spaces will be inserted after ``<`` and before ``>``
+ /// If ``true``, spaces will be inserted after ``<`` and before ``>``
/// in template argument lists.
/// \code
/// true: false:
@@ -1531,7 +1606,7 @@ struct FormatStyle {
/// \endcode
bool SpacesInAngles;
- /// \brief If ``true``, spaces are inserted inside container literals (e.g.
+ /// If ``true``, spaces are inserted inside container literals (e.g.
/// ObjC and Javascript array and dict literals).
/// \code{.js}
/// true: false:
@@ -1540,21 +1615,21 @@ struct FormatStyle {
/// \endcode
bool SpacesInContainerLiterals;
- /// \brief If ``true``, spaces may be inserted into C style casts.
+ /// If ``true``, spaces may be inserted into C style casts.
/// \code
/// true: false:
/// x = ( int32 )y vs. x = (int32)y
/// \endcode
bool SpacesInCStyleCastParentheses;
- /// \brief If ``true``, spaces will be inserted after ``(`` and before ``)``.
+ /// If ``true``, spaces will be inserted after ``(`` and before ``)``.
/// \code
/// true: false:
/// t f( Deleted & ) & = delete; vs. t f(Deleted &) & = delete;
/// \endcode
bool SpacesInParentheses;
- /// \brief If ``true``, spaces will be inserted after ``[`` and before ``]``.
+ /// If ``true``, spaces will be inserted after ``[`` and before ``]``.
/// Lambdas or unspecified size array declarations will not be affected.
/// \code
/// true: false:
@@ -1563,7 +1638,7 @@ struct FormatStyle {
/// \endcode
bool SpacesInSquareBrackets;
- /// \brief Supported language standards.
+ /// Supported language standards.
enum LanguageStandard {
/// Use C++03-compatible syntax.
LS_Cpp03,
@@ -1574,14 +1649,14 @@ struct FormatStyle {
LS_Auto
};
- /// \brief Format compatible with this standard, e.g. use ``A<A<int> >``
+ /// Format compatible with this standard, e.g. use ``A<A<int> >``
/// instead of ``A<A<int>>`` for ``LS_Cpp03``.
LanguageStandard Standard;
- /// \brief The number of columns used for tab stops.
+ /// The number of columns used for tab stops.
unsigned TabWidth;
- /// \brief Different ways to use tab in formatting.
+ /// Different ways to use tab in formatting.
enum UseTabStyle {
/// Never use tab.
UT_Never,
@@ -1594,7 +1669,7 @@ struct FormatStyle {
UT_Always
};
- /// \brief The way to use tab characters in the resulting file.
+ /// The way to use tab characters in the resulting file.
UseTabStyle UseTab;
bool operator==(const FormatStyle &R) const {
@@ -1630,7 +1705,7 @@ struct FormatStyle {
BreakAfterJavaFieldAnnotations == R.BreakAfterJavaFieldAnnotations &&
BreakStringLiterals == R.BreakStringLiterals &&
ColumnLimit == R.ColumnLimit && CommentPragmas == R.CommentPragmas &&
- BreakBeforeInheritanceComma == R.BreakBeforeInheritanceComma &&
+ BreakInheritanceList == R.BreakInheritanceList &&
ConstructorInitializerAllOnOneLineOrOnePerLine ==
R.ConstructorInitializerAllOnOneLineOrOnePerLine &&
ConstructorInitializerIndentWidth ==
@@ -1643,8 +1718,8 @@ struct FormatStyle {
R.ExperimentalAutoDetectBinPacking &&
FixNamespaceComments == R.FixNamespaceComments &&
ForEachMacros == R.ForEachMacros &&
- IncludeBlocks == R.IncludeBlocks &&
- IncludeCategories == R.IncludeCategories &&
+ IncludeStyle.IncludeBlocks == R.IncludeStyle.IncludeBlocks &&
+ IncludeStyle.IncludeCategories == R.IncludeStyle.IncludeCategories &&
IndentCaseLabels == R.IndentCaseLabels &&
IndentPPDirectives == R.IndentPPDirectives &&
IndentWidth == R.IndentWidth && Language == R.Language &&
@@ -1657,11 +1732,11 @@ struct FormatStyle {
MacroBlockEnd == R.MacroBlockEnd &&
MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
NamespaceIndentation == R.NamespaceIndentation &&
+ ObjCBinPackProtocolList == R.ObjCBinPackProtocolList &&
ObjCBlockIndentWidth == R.ObjCBlockIndentWidth &&
ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty &&
ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList &&
- PenaltyBreakAssignment ==
- R.PenaltyBreakAssignment &&
+ PenaltyBreakAssignment == R.PenaltyBreakAssignment &&
PenaltyBreakBeforeFirstCallParameter ==
R.PenaltyBreakBeforeFirstCallParameter &&
PenaltyBreakComment == R.PenaltyBreakComment &&
@@ -1669,12 +1744,20 @@ struct FormatStyle {
PenaltyBreakString == R.PenaltyBreakString &&
PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
+ PenaltyBreakTemplateDeclaration ==
+ R.PenaltyBreakTemplateDeclaration &&
PointerAlignment == R.PointerAlignment &&
RawStringFormats == R.RawStringFormats &&
SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
SpaceAfterTemplateKeyword == R.SpaceAfterTemplateKeyword &&
SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators &&
+ SpaceBeforeCpp11BracedList == R.SpaceBeforeCpp11BracedList &&
+ SpaceBeforeCtorInitializerColon ==
+ R.SpaceBeforeCtorInitializerColon &&
+ SpaceBeforeInheritanceColon == R.SpaceBeforeInheritanceColon &&
SpaceBeforeParens == R.SpaceBeforeParens &&
+ SpaceBeforeRangeBasedForLoopColon ==
+ R.SpaceBeforeRangeBasedForLoopColon &&
SpaceInEmptyParentheses == R.SpaceInEmptyParentheses &&
SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments &&
SpacesInAngles == R.SpacesInAngles &&
@@ -1685,38 +1768,75 @@ struct FormatStyle {
Standard == R.Standard && TabWidth == R.TabWidth &&
UseTab == R.UseTab;
}
+
+ llvm::Optional<FormatStyle> GetLanguageStyle(LanguageKind Language) const;
+
+ // Stores per-language styles. A FormatStyle instance inside has an empty
+ // StyleSet. A FormatStyle instance returned by the Get method has its
+ // StyleSet set to a copy of the originating StyleSet, effectively keeping the
+ // internal representation of that StyleSet alive.
+ //
+ // The memory management and ownership reminds of a birds nest: chicks
+ // leaving the nest take photos of the nest with them.
+ struct FormatStyleSet {
+ typedef std::map<FormatStyle::LanguageKind, FormatStyle> MapType;
+
+ llvm::Optional<FormatStyle> Get(FormatStyle::LanguageKind Language) const;
+
+ // Adds \p Style to this FormatStyleSet. Style must not have an associated
+ // FormatStyleSet.
+ // Style.Language should be different than LK_None. If this FormatStyleSet
+ // already contains an entry for Style.Language, that gets replaced with the
+ // passed Style.
+ void Add(FormatStyle Style);
+
+ // Clears this FormatStyleSet.
+ void Clear();
+
+ private:
+ std::shared_ptr<MapType> Styles;
+ };
+
+ static FormatStyleSet BuildStyleSetFromConfiguration(
+ const FormatStyle &MainStyle,
+ const std::vector<FormatStyle> &ConfigurationStyles);
+
+private:
+ FormatStyleSet StyleSet;
+
+ friend std::error_code parseConfiguration(StringRef Text, FormatStyle *Style);
};
-/// \brief Returns a format style complying with the LLVM coding standards:
+/// Returns a format style complying with the LLVM coding standards:
/// http://llvm.org/docs/CodingStandards.html.
FormatStyle getLLVMStyle();
-/// \brief Returns a format style complying with one of Google's style guides:
+/// Returns a format style complying with one of Google's style guides:
/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml.
/// http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml.
/// https://developers.google.com/protocol-buffers/docs/style.
FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language);
-/// \brief Returns a format style complying with Chromium's style guide:
+/// Returns a format style complying with Chromium's style guide:
/// http://www.chromium.org/developers/coding-style.
FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language);
-/// \brief Returns a format style complying with Mozilla's style guide:
+/// Returns a format style complying with Mozilla's style guide:
/// https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style.
FormatStyle getMozillaStyle();
-/// \brief Returns a format style complying with Webkit's style guide:
+/// Returns a format style complying with Webkit's style guide:
/// http://www.webkit.org/coding/coding-style.html
FormatStyle getWebKitStyle();
-/// \brief Returns a format style complying with GNU Coding Standards:
+/// Returns a format style complying with GNU Coding Standards:
/// http://www.gnu.org/prep/standards/standards.html
FormatStyle getGNUStyle();
-/// \brief Returns style indicating formatting should be not applied at all.
+/// Returns style indicating formatting should be not applied at all.
FormatStyle getNoStyle();
-/// \brief Gets a predefined style for the specified language by name.
+/// Gets a predefined style for the specified language by name.
///
/// Currently supported names: LLVM, Google, Chromium, Mozilla. Names are
/// compared case-insensitively.
@@ -1725,66 +1845,64 @@ FormatStyle getNoStyle();
bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
FormatStyle *Style);
-/// \brief Parse configuration from YAML-formatted text.
+/// Parse configuration from YAML-formatted text.
///
/// Style->Language is used to get the base style, if the ``BasedOnStyle``
/// option is present.
///
+/// The FormatStyleSet of Style is reset.
+///
/// When ``BasedOnStyle`` is not present, options not present in the YAML
/// document, are retained in \p Style.
std::error_code parseConfiguration(StringRef Text, FormatStyle *Style);
-/// \brief Gets configuration in a YAML string.
+/// Gets configuration in a YAML string.
std::string configurationAsText(const FormatStyle &Style);
-/// \brief Returns the replacements necessary to sort all ``#include`` blocks
+/// Returns the replacements necessary to sort all ``#include`` blocks
/// that are affected by ``Ranges``.
tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code,
ArrayRef<tooling::Range> Ranges,
StringRef FileName,
unsigned *Cursor = nullptr);
-/// \brief Returns the replacements corresponding to applying and formatting
+/// Returns the replacements corresponding to applying and formatting
/// \p Replaces on success; otheriwse, return an llvm::Error carrying
/// llvm::StringError.
llvm::Expected<tooling::Replacements>
formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
const FormatStyle &Style);
-/// \brief Returns the replacements corresponding to applying \p Replaces and
+/// Returns the replacements corresponding to applying \p Replaces and
/// cleaning up the code after that on success; otherwise, return an llvm::Error
/// carrying llvm::StringError.
/// This also supports inserting/deleting C++ #include directives:
/// - If a replacement has offset UINT_MAX, length 0, and a replacement text
/// that is an #include directive, this will insert the #include into the
-/// correct block in the \p Code. When searching for points to insert new
-/// header, this ignores #include's after the #include block(s) in the
-/// beginning of a file to avoid inserting headers into code sections where
-/// new #include's should not be added by default. These code sections
-/// include:
-/// - raw string literals (containing #include).
-/// - #if blocks.
-/// - Special #include's among declarations (e.g. functions).
+/// correct block in the \p Code.
/// - If a replacement has offset UINT_MAX, length 1, and a replacement text
/// that is the name of the header to be removed, the header will be removed
/// from \p Code if it exists.
+/// The include manipulation is done via `tooling::HeaderInclude`, see its
+/// documentation for more details on how include insertion points are found and
+/// what edits are produced.
llvm::Expected<tooling::Replacements>
cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces,
const FormatStyle &Style);
-/// \brief Represents the status of a formatting attempt.
+/// Represents the status of a formatting attempt.
struct FormattingAttemptStatus {
- /// \brief A value of ``false`` means that any of the affected ranges were not
+ /// A value of ``false`` means that any of the affected ranges were not
/// formatted due to a non-recoverable syntax error.
bool FormatComplete = true;
- /// \brief If ``FormatComplete`` is false, ``Line`` records a one-based
+ /// If ``FormatComplete`` is false, ``Line`` records a one-based
/// original line number at which a syntax error might have occurred. This is
/// based on a best-effort analysis and could be imprecise.
unsigned Line = 0;
};
-/// \brief Reformats the given \p Ranges in \p Code.
+/// Reformats the given \p Ranges in \p Code.
///
/// Each range is extended on either end to its next bigger logic unit, i.e.
/// everything that might influence its formatting or might be influenced by its
@@ -1800,7 +1918,7 @@ tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
StringRef FileName = "<stdin>",
FormattingAttemptStatus *Status = nullptr);
-/// \brief Same as above, except if ``IncompleteFormat`` is non-null, its value
+/// Same as above, except if ``IncompleteFormat`` is non-null, its value
/// will be set to true if any of the affected ranges were not formatted due to
/// a non-recoverable syntax error.
tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
@@ -1808,7 +1926,7 @@ tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
StringRef FileName,
bool *IncompleteFormat);
-/// \brief Clean up any erroneous/redundant code in the given \p Ranges in \p
+/// Clean up any erroneous/redundant code in the given \p Ranges in \p
/// Code.
///
/// Returns the ``Replacements`` that clean up all \p Ranges in \p Code.
@@ -1816,7 +1934,7 @@ tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code,
ArrayRef<tooling::Range> Ranges,
StringRef FileName = "<stdin>");
-/// \brief Fix namespace end comments in the given \p Ranges in \p Code.
+/// Fix namespace end comments in the given \p Ranges in \p Code.
///
/// Returns the ``Replacements`` that fix the namespace comments in all
/// \p Ranges in \p Code.
@@ -1825,7 +1943,7 @@ tooling::Replacements fixNamespaceEndComments(const FormatStyle &Style,
ArrayRef<tooling::Range> Ranges,
StringRef FileName = "<stdin>");
-/// \brief Sort consecutive using declarations in the given \p Ranges in
+/// Sort consecutive using declarations in the given \p Ranges in
/// \p Code.
///
/// Returns the ``Replacements`` that sort the using declarations in all
@@ -1835,17 +1953,26 @@ tooling::Replacements sortUsingDeclarations(const FormatStyle &Style,
ArrayRef<tooling::Range> Ranges,
StringRef FileName = "<stdin>");
-/// \brief Returns the ``LangOpts`` that the formatter expects you to set.
+/// Returns the ``LangOpts`` that the formatter expects you to set.
///
/// \param Style determines specific settings for lexing mode.
LangOptions getFormattingLangOpts(const FormatStyle &Style = getLLVMStyle());
-/// \brief Description to be used for help text for a ``llvm::cl`` option for
+/// Description to be used for help text for a ``llvm::cl`` option for
/// specifying format style. The description is closely related to the operation
/// of ``getStyle()``.
extern const char *StyleOptionHelpDescription;
-/// \brief Construct a FormatStyle based on ``StyleName``.
+/// The suggested format style to use by default. This allows tools using
+/// `getStyle` to have a consistent default style.
+/// Different builds can modify the value to the preferred styles.
+extern const char *DefaultFormatStyle;
+
+/// The suggested predefined style to use as the fallback style in `getStyle`.
+/// Different builds can modify the value to the preferred styles.
+extern const char *DefaultFallbackStyle;
+
+/// Construct a FormatStyle based on ``StyleName``.
///
/// ``StyleName`` can take several forms:
/// * "{<key>: <value>, ...}" - Set specic style parameters.
@@ -1874,7 +2001,11 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
StringRef Code = "",
vfs::FileSystem *FS = nullptr);
-// \brief Returns a string representation of ``Language``.
+// Guesses the language from the ``FileName`` and ``Code`` to be formatted.
+// Defaults to FormatStyle::LK_Cpp.
+FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code);
+
+// Returns a string representation of ``Language``.
inline StringRef getLanguageName(FormatStyle::LanguageKind Language) {
switch (Language) {
case FormatStyle::LK_Cpp:
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 53975a07ea944..2a13527df1350 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -34,9 +34,10 @@ class TargetOptions;
std::unique_ptr<ASTConsumer> CreateASTPrinter(std::unique_ptr<raw_ostream> OS,
StringRef FilterString);
-// AST dumper: dumps the raw AST in human-readable form to stderr; this is
-// intended for debugging.
-std::unique_ptr<ASTConsumer> CreateASTDumper(StringRef FilterString,
+// AST dumper: dumps the raw AST in human-readable form to the given output
+// stream, or stdout if OS is nullptr.
+std::unique_ptr<ASTConsumer> CreateASTDumper(std::unique_ptr<raw_ostream> OS,
+ StringRef FilterString,
bool DumpDecls, bool Deserialize,
bool DumpLookups);
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 5d04dcd19119a..9f529ba0e0e85 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -1,4 +1,4 @@
-//===--- ASTUnit.h - ASTUnit utility ----------------------------*- C++ -*-===//
+//===- ASTUnit.h - ASTUnit utility ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,8 +16,11 @@
#include "clang-c/Index.h"
#include "clang/AST/ASTContext.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Lex/HeaderSearchOptions.h"
@@ -26,48 +29,62 @@
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Frontend/PrecompiledPreamble.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/MD5.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <memory>
#include <string>
-#include <sys/types.h>
#include <utility>
#include <vector>
namespace llvm {
- class MemoryBuffer;
-}
+
+class MemoryBuffer;
+
+} // namespace llvm
namespace clang {
-class Sema;
+
class ASTContext;
+class ASTDeserializationListener;
+class ASTMutationListener;
class ASTReader;
-class CompilerInvocation;
class CompilerInstance;
+class CompilerInvocation;
class Decl;
-class DiagnosticsEngine;
class FileEntry;
class FileManager;
+class FrontendAction;
class HeaderSearch;
class InputKind;
class MemoryBufferCache;
-class Preprocessor;
-class PreprocessorOptions;
class PCHContainerOperations;
class PCHContainerReader;
+class Preprocessor;
+class PreprocessorOptions;
+class Sema;
class TargetInfo;
-class FrontendAction;
-class ASTDeserializationListener;
namespace vfs {
+
class FileSystem;
-}
-/// \brief Utility class for loading a ASTContext from an AST file.
-///
+} // namespace vfs
+
+/// \brief Enumerates the available scopes for skipping function bodies.
+enum class SkipFunctionBodiesScope { None, Preamble, PreambleAndMainFile };
+
+/// Utility class for loading a ASTContext from an AST file.
class ASTUnit {
public:
struct StandaloneFixIt {
@@ -83,7 +100,7 @@ public:
std::string Message;
std::string Filename;
unsigned LocOffset;
- std::vector<std::pair<unsigned, unsigned> > Ranges;
+ std::vector<std::pair<unsigned, unsigned>> Ranges;
std::vector<StandaloneFixIt> FixIts;
};
@@ -101,18 +118,18 @@ private:
std::shared_ptr<HeaderSearchOptions> HSOpts;
std::shared_ptr<PreprocessorOptions> PPOpts;
IntrusiveRefCntPtr<ASTReader> Reader;
- bool HadModuleLoaderFatalFailure;
+ bool HadModuleLoaderFatalFailure = false;
struct ASTWriterData;
std::unique_ptr<ASTWriterData> WriterData;
FileSystemOptions FileSystemOpts;
- /// \brief The AST consumer that received information about the translation
+ /// The AST consumer that received information about the translation
/// unit as it was parsed or loaded.
std::unique_ptr<ASTConsumer> Consumer;
- /// \brief The semantic analysis object used to type-check the translation
+ /// The semantic analysis object used to type-check the translation
/// unit.
std::unique_ptr<Sema> TheSema;
@@ -126,22 +143,22 @@ private:
// OnlyLocalDecls - when true, walking this AST should only visit declarations
// that come from the AST itself, not from included precompiled headers.
// FIXME: This is temporary; eventually, CIndex will always do this.
- bool OnlyLocalDecls;
+ bool OnlyLocalDecls = false;
- /// \brief Whether to capture any diagnostics produced.
- bool CaptureDiagnostics;
+ /// Whether to capture any diagnostics produced.
+ bool CaptureDiagnostics = false;
- /// \brief Track whether the main file was loaded from an AST or not.
+ /// Track whether the main file was loaded from an AST or not.
bool MainFileIsAST;
- /// \brief What kind of translation unit this AST represents.
- TranslationUnitKind TUKind;
+ /// What kind of translation unit this AST represents.
+ TranslationUnitKind TUKind = TU_Complete;
- /// \brief Whether we should time each operation.
+ /// Whether we should time each operation.
bool WantTiming;
- /// \brief Whether the ASTUnit should delete the remapped buffers.
- bool OwnsRemappedFileBuffers;
+ /// Whether the ASTUnit should delete the remapped buffers.
+ bool OwnsRemappedFileBuffers = true;
/// Track the top-level decls which appeared in an ASTUnit which was loaded
/// from a source file.
@@ -152,36 +169,36 @@ private:
// more scalable search mechanisms.
std::vector<Decl*> TopLevelDecls;
- /// \brief Sorted (by file offset) vector of pairs of file offset/Decl.
- typedef SmallVector<std::pair<unsigned, Decl *>, 64> LocDeclsTy;
- typedef llvm::DenseMap<FileID, LocDeclsTy *> FileDeclsTy;
+ /// Sorted (by file offset) vector of pairs of file offset/Decl.
+ using LocDeclsTy = SmallVector<std::pair<unsigned, Decl *>, 64>;
+ using FileDeclsTy = llvm::DenseMap<FileID, LocDeclsTy *>;
- /// \brief Map from FileID to the file-level declarations that it contains.
+ /// Map from FileID to the file-level declarations that it contains.
/// The files and decls are only local (and non-preamble) ones.
FileDeclsTy FileDecls;
/// The name of the original source file used to generate this ASTUnit.
std::string OriginalSourceFile;
- /// \brief The set of diagnostics produced when creating the preamble.
+ /// The set of diagnostics produced when creating the preamble.
SmallVector<StandaloneDiagnostic, 4> PreambleDiagnostics;
- /// \brief The set of diagnostics produced when creating this
+ /// The set of diagnostics produced when creating this
/// translation unit.
SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
- /// \brief The set of diagnostics produced when failing to parse, e.g. due
+ /// The set of diagnostics produced when failing to parse, e.g. due
/// to failure to load the PCH.
SmallVector<StoredDiagnostic, 4> FailedParseDiagnostics;
- /// \brief The number of stored diagnostics that come from the driver
+ /// The number of stored diagnostics that come from the driver
/// itself.
///
/// Diagnostics that come from the driver are retained from one parse to
/// the next.
- unsigned NumStoredDiagnosticsFromDriver;
+ unsigned NumStoredDiagnosticsFromDriver = 0;
- /// \brief Counter that determines when we want to try building a
+ /// Counter that determines when we want to try building a
/// precompiled preamble.
///
/// If zero, we will never build a precompiled preamble. Otherwise,
@@ -190,45 +207,44 @@ private:
/// we'll attempt to rebuild the precompiled header. This way, if
/// building the precompiled preamble fails, we won't try again for
/// some number of calls.
- unsigned PreambleRebuildCounter;
+ unsigned PreambleRebuildCounter = 0;
- /// \brief Cache pairs "filename - source location"
+ /// Cache pairs "filename - source location"
///
/// Cache contains only source locations from preamble so it is
/// guaranteed that they stay valid when the SourceManager is recreated.
- /// This cache is used when loading preambule to increase performance
+ /// This cache is used when loading preamble to increase performance
/// of that loading. It must be cleared when preamble is recreated.
llvm::StringMap<SourceLocation> PreambleSrcLocCache;
-private:
/// The contents of the preamble.
llvm::Optional<PrecompiledPreamble> Preamble;
- /// \brief When non-NULL, this is the buffer used to store the contents of
+ /// When non-NULL, this is the buffer used to store the contents of
/// the main file when it has been padded for use with the precompiled
/// preamble.
std::unique_ptr<llvm::MemoryBuffer> SavedMainFileBuffer;
- /// \brief The number of warnings that occurred while parsing the preamble.
+ /// The number of warnings that occurred while parsing the preamble.
///
/// This value will be used to restore the state of the \c DiagnosticsEngine
/// object when re-using the precompiled preamble. Note that only the
/// number of warnings matters, since we will not save the preamble
/// when any errors are present.
- unsigned NumWarningsInPreamble;
+ unsigned NumWarningsInPreamble = 0;
- /// \brief A list of the serialization ID numbers for each of the top-level
+ /// A list of the serialization ID numbers for each of the top-level
/// declarations parsed within the precompiled preamble.
std::vector<serialization::DeclID> TopLevelDeclsInPreamble;
- /// \brief Whether we should be caching code-completion results.
+ /// Whether we should be caching code-completion results.
bool ShouldCacheCodeCompletionResults : 1;
- /// \brief Whether to include brief documentation within the set of code
+ /// Whether to include brief documentation within the set of code
/// completions cached.
bool IncludeBriefCommentsInCodeCompletion : 1;
- /// \brief True if non-system source files should be treated as volatile
+ /// True if non-system source files should be treated as volatile
/// (likely to change while trying to use them).
bool UserFilesAreVolatile : 1;
@@ -243,14 +259,14 @@ private:
void clearFileLevelDecls();
public:
- /// \brief A cached code-completion result, which may be introduced in one of
+ /// A cached code-completion result, which may be introduced in one of
/// many different contexts.
struct CachedCodeCompletionResult {
- /// \brief The code-completion string corresponding to this completion
+ /// The code-completion string corresponding to this completion
/// result.
CodeCompletionString *Completion;
- /// \brief A bitmask that indicates which code-completion contexts should
+ /// A bitmask that indicates which code-completion contexts should
/// contain this completion result.
///
/// The bits in the bitmask correspond to the values of
@@ -259,20 +275,20 @@ public:
/// several different contexts.
uint64_t ShowInContexts;
- /// \brief The priority given to this code-completion result.
+ /// The priority given to this code-completion result.
unsigned Priority;
- /// \brief The libclang cursor kind corresponding to this code-completion
+ /// The libclang cursor kind corresponding to this code-completion
/// result.
CXCursorKind Kind;
- /// \brief The availability of this code-completion result.
+ /// The availability of this code-completion result.
CXAvailabilityKind Availability;
- /// \brief The simplified type class for a non-macro completion result.
+ /// The simplified type class for a non-macro completion result.
SimplifiedTypeClass TypeClass;
- /// \brief The type of a non-macro completion result, stored as a unique
+ /// The type of a non-macro completion result, stored as a unique
/// integer used by the string map of cached completion types.
///
/// This value will be zero if the type is not known, or a unique value
@@ -281,13 +297,13 @@ public:
unsigned Type;
};
- /// \brief Retrieve the mapping from formatted type names to unique type
+ /// Retrieve the mapping from formatted type names to unique type
/// identifiers.
- llvm::StringMap<unsigned> &getCachedCompletionTypes() {
+ llvm::StringMap<unsigned> &getCachedCompletionTypes() {
return CachedCompletionTypes;
}
- /// \brief Retrieve the allocator used to cache global code completions.
+ /// Retrieve the allocator used to cache global code completions.
std::shared_ptr<GlobalCodeCompletionAllocator>
getCachedCompletionAllocator() {
return CachedCompletionAllocator;
@@ -301,50 +317,50 @@ public:
}
private:
- /// \brief Allocator used to store cached code completions.
+ /// Allocator used to store cached code completions.
std::shared_ptr<GlobalCodeCompletionAllocator> CachedCompletionAllocator;
std::unique_ptr<CodeCompletionTUInfo> CCTUInfo;
- /// \brief The set of cached code-completion results.
+ /// The set of cached code-completion results.
std::vector<CachedCodeCompletionResult> CachedCompletionResults;
- /// \brief A mapping from the formatted type name to a unique number for that
+ /// A mapping from the formatted type name to a unique number for that
/// type, which is used for type equality comparisons.
llvm::StringMap<unsigned> CachedCompletionTypes;
- /// \brief A string hash of the top-level declaration and macro definition
+ /// A string hash of the top-level declaration and macro definition
/// names processed the last time that we reparsed the file.
///
/// This hash value is used to determine when we need to refresh the
/// global code-completion cache.
- unsigned CompletionCacheTopLevelHashValue;
+ unsigned CompletionCacheTopLevelHashValue = 0;
- /// \brief A string hash of the top-level declaration and macro definition
+ /// A string hash of the top-level declaration and macro definition
/// names processed the last time that we reparsed the precompiled preamble.
///
/// This hash value is used to determine when we need to refresh the
/// global code-completion cache after a rebuild of the precompiled preamble.
- unsigned PreambleTopLevelHashValue;
+ unsigned PreambleTopLevelHashValue = 0;
- /// \brief The current hash value for the top-level declaration and macro
+ /// The current hash value for the top-level declaration and macro
/// definition names
- unsigned CurrentTopLevelHashValue;
+ unsigned CurrentTopLevelHashValue = 0;
- /// \brief Bit used by CIndex to mark when a translation unit may be in an
+ /// Bit used by CIndex to mark when a translation unit may be in an
/// inconsistent state, and is not safe to free.
unsigned UnsafeToFree : 1;
- /// \brief Cache any "global" code-completion results, so that we can avoid
+ /// \brief Enumerator specifying the scope for skipping function bodies.
+ SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
+
+ /// Cache any "global" code-completion results, so that we can avoid
/// recomputing them with each completion.
void CacheCodeCompletionResults();
- /// \brief Clear out and deallocate
+ /// Clear out and deallocate
void ClearCachedCompletionResults();
- ASTUnit(const ASTUnit &) = delete;
- void operator=(const ASTUnit &) = delete;
-
explicit ASTUnit(bool MainFileIsAST);
bool Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
@@ -353,16 +369,16 @@ private:
std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- const CompilerInvocation &PreambleInvocationIn,
+ CompilerInvocation &PreambleInvocationIn,
IntrusiveRefCntPtr<vfs::FileSystem> VFS, bool AllowRebuild = true,
unsigned MaxLines = 0);
void RealizeTopLevelDeclsFromPreamble();
- /// \brief Transfers ownership of the objects (like SourceManager) from
+ /// Transfers ownership of the objects (like SourceManager) from
/// \param CI to this ASTUnit.
void transferASTDataFromCompilerInstance(CompilerInstance &CI);
- /// \brief Allows us to assert that ASTUnit is not being used concurrently,
+ /// Allows us to assert that ASTUnit is not being used concurrently,
/// which is not supported.
///
/// Clients should create instances of the ConcurrencyCheck class whenever
@@ -382,21 +398,23 @@ private:
ConcurrencyState ConcurrencyCheckValue;
public:
+ friend class ConcurrencyCheck;
+
class ConcurrencyCheck {
ASTUnit &Self;
public:
- explicit ConcurrencyCheck(ASTUnit &Self)
- : Self(Self)
- {
+ explicit ConcurrencyCheck(ASTUnit &Self) : Self(Self) {
Self.ConcurrencyCheckValue.start();
}
+
~ConcurrencyCheck() {
Self.ConcurrencyCheckValue.finish();
}
};
- friend class ConcurrencyCheck;
+ ASTUnit(const ASTUnit &) = delete;
+ ASTUnit &operator=(const ASTUnit &) = delete;
~ASTUnit();
bool isMainFileAST() const { return MainFileIsAST; }
@@ -405,22 +423,32 @@ public:
void setUnsafeToFree(bool Value) { UnsafeToFree = Value; }
const DiagnosticsEngine &getDiagnostics() const { return *Diagnostics; }
- DiagnosticsEngine &getDiagnostics() { return *Diagnostics; }
+ DiagnosticsEngine &getDiagnostics() { return *Diagnostics; }
const SourceManager &getSourceManager() const { return *SourceMgr; }
- SourceManager &getSourceManager() { return *SourceMgr; }
+ SourceManager &getSourceManager() { return *SourceMgr; }
const Preprocessor &getPreprocessor() const { return *PP; }
- Preprocessor &getPreprocessor() { return *PP; }
+ Preprocessor &getPreprocessor() { return *PP; }
std::shared_ptr<Preprocessor> getPreprocessorPtr() const { return PP; }
const ASTContext &getASTContext() const { return *Ctx; }
- ASTContext &getASTContext() { return *Ctx; }
+ ASTContext &getASTContext() { return *Ctx; }
void setASTContext(ASTContext *ctx) { Ctx = ctx; }
void setPreprocessor(std::shared_ptr<Preprocessor> pp);
+ /// Enable source-range based diagnostic messages.
+ ///
+ /// If diagnostic messages with source-range information are to be expected
+ /// and AST comes not from file (e.g. after LoadFromCompilerInvocation) this
+ /// function has to be called.
+ /// The function is to be called only once and the AST should be associated
+ /// with the same source file afterwards.
+ void enableSourceFileDiagnostics();
+
bool hasSema() const { return (bool)TheSema; }
+
Sema &getSema() const {
assert(TheSema && "ASTUnit does not have a Sema object!");
return *TheSema;
@@ -442,7 +470,7 @@ public:
}
const FileManager &getFileManager() const { return *FileMgr; }
- FileManager &getFileManager() { return *FileMgr; }
+ FileManager &getFileManager() { return *FileMgr; }
const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
@@ -462,10 +490,10 @@ public:
StringRef getMainFileName() const;
- /// \brief If this ASTUnit came from an AST file, returns the filename for it.
+ /// If this ASTUnit came from an AST file, returns the filename for it.
StringRef getASTFileName() const;
- typedef std::vector<Decl *>::iterator top_level_iterator;
+ using top_level_iterator = std::vector<Decl *>::iterator;
top_level_iterator top_level_begin() {
assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
@@ -491,26 +519,26 @@ public:
return TopLevelDeclsInPreamble.empty() && TopLevelDecls.empty();
}
- /// \brief Add a new top-level declaration.
+ /// Add a new top-level declaration.
void addTopLevelDecl(Decl *D) {
TopLevelDecls.push_back(D);
}
- /// \brief Add a new local file-level declaration.
+ /// Add a new local file-level declaration.
void addFileLevelDecl(Decl *D);
- /// \brief Get the decls that are contained in a file in the Offset/Length
+ /// 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.
void findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
SmallVectorImpl<Decl *> &Decls);
- /// \brief Retrieve a reference to the current top-level name hash value.
+ /// Retrieve a reference to the current top-level name hash value.
///
/// Note: This is used internally by the top-level tracking action
unsigned &getCurrentTopLevelHashValue() { return CurrentTopLevelHashValue; }
- /// \brief Get the source location for the given file:line:col triplet.
+ /// Get the source location for the given file:line:col triplet.
///
/// The difference with SourceManager::getLocation is that this method checks
/// whether the requested location points inside the precompiled preamble
@@ -518,15 +546,15 @@ public:
SourceLocation getLocation(const FileEntry *File,
unsigned Line, unsigned Col) const;
- /// \brief Get the source location for the given file:offset pair.
+ /// Get the source location for the given file:offset pair.
SourceLocation getLocation(const FileEntry *File, unsigned Offset) const;
- /// \brief If \p Loc is a loaded location from the preamble, returns
+ /// If \p Loc is a loaded location from the preamble, returns
/// the corresponding local location of the main file, otherwise it returns
/// \p Loc.
SourceLocation mapLocationFromPreamble(SourceLocation Loc) const;
- /// \brief If \p Loc is a local location of the main file but inside the
+ /// If \p Loc is a local location of the main file but inside the
/// preamble chunk, returns the corresponding loaded location from the
/// preamble, otherwise it returns \p Loc.
SourceLocation mapLocationToPreamble(SourceLocation Loc) const;
@@ -549,20 +577,25 @@ public:
}
// Retrieve the diagnostics associated with this AST
- typedef StoredDiagnostic *stored_diag_iterator;
- typedef const StoredDiagnostic *stored_diag_const_iterator;
+ using stored_diag_iterator = StoredDiagnostic *;
+ using stored_diag_const_iterator = const StoredDiagnostic *;
+
stored_diag_const_iterator stored_diag_begin() const {
return StoredDiagnostics.begin();
}
+
stored_diag_iterator stored_diag_begin() {
return StoredDiagnostics.begin();
}
+
stored_diag_const_iterator stored_diag_end() const {
return StoredDiagnostics.end();
}
+
stored_diag_iterator stored_diag_end() {
return StoredDiagnostics.end();
}
+
unsigned stored_diag_size() const { return StoredDiagnostics.size(); }
stored_diag_iterator stored_diag_afterDriver_begin() {
@@ -571,8 +604,8 @@ public:
return StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver;
}
- typedef std::vector<CachedCodeCompletionResult>::iterator
- cached_completion_iterator;
+ using cached_completion_iterator =
+ std::vector<CachedCodeCompletionResult>::iterator;
cached_completion_iterator cached_completion_begin() {
return CachedCompletionResults.begin();
@@ -586,43 +619,43 @@ public:
return CachedCompletionResults.size();
}
- /// \brief Returns an iterator range for the local preprocessing entities
+ /// Returns an iterator range for the local preprocessing entities
/// of the local Preprocessor, if this is a parsed source file, or the loaded
/// preprocessing entities of the primary module if this is an AST file.
llvm::iterator_range<PreprocessingRecord::iterator>
getLocalPreprocessingEntities() const;
- /// \brief Type for a function iterating over a number of declarations.
+ /// Type for a function iterating over a number of declarations.
/// \returns true to continue iteration and false to abort.
- typedef bool (*DeclVisitorFn)(void *context, const Decl *D);
+ using DeclVisitorFn = bool (*)(void *context, const Decl *D);
- /// \brief Iterate over local declarations (locally parsed if this is a parsed
+ /// Iterate over local declarations (locally parsed if this is a parsed
/// source file or the loaded declarations of the primary module if this is an
/// AST file).
/// \returns true if the iteration was complete or false if it was aborted.
bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn);
- /// \brief Get the PCH file if one was included.
+ /// Get the PCH file if one was included.
const FileEntry *getPCHFile();
- /// \brief Returns true if the ASTUnit was constructed from a serialized
+ /// Returns true if the ASTUnit was constructed from a serialized
/// module file.
bool isModuleFile() const;
std::unique_ptr<llvm::MemoryBuffer>
getBufferForFile(StringRef Filename, std::string *ErrorStr = nullptr);
- /// \brief Determine what kind of translation unit this AST represents.
+ /// Determine what kind of translation unit this AST represents.
TranslationUnitKind getTranslationUnitKind() const { return TUKind; }
- /// \brief Determine the input kind this AST unit represents.
+ /// Determine the input kind this AST unit represents.
InputKind getInputKind() const;
- /// \brief A mapping from a file name to the memory buffer that stores the
+ /// A mapping from a file name to the memory buffer that stores the
/// remapped contents of that file.
- typedef std::pair<std::string, llvm::MemoryBuffer *> RemappedFile;
+ using RemappedFile = std::pair<std::string, llvm::MemoryBuffer *>;
- /// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation.
+ /// Create a ASTUnit. Gets ownership of the passed CompilerInvocation.
static std::unique_ptr<ASTUnit>
create(std::shared_ptr<CompilerInvocation> CI,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool CaptureDiagnostics,
@@ -631,13 +664,15 @@ public:
enum WhatToLoad {
/// Load options and the preprocessor state.
LoadPreprocessorOnly,
+
/// Load the AST, but do not restore Sema state.
LoadASTOnly,
+
/// Load everything, including Sema.
LoadEverything
};
- /// \brief Create a ASTUnit from an AST file.
+ /// Create a ASTUnit from an AST file.
///
/// \param Filename - The AST file to load.
///
@@ -656,7 +691,7 @@ public:
bool UserFilesAreVolatile = false);
private:
- /// \brief Helper function for \c LoadFromCompilerInvocation() and
+ /// Helper function for \c LoadFromCompilerInvocation() and
/// \c LoadFromCommandLine(), which loads an AST from a compiler invocation.
///
/// \param PrecompilePreambleAfterNParses After how many parses the preamble
@@ -676,8 +711,7 @@ private:
IntrusiveRefCntPtr<vfs::FileSystem> VFS);
public:
-
- /// \brief Create an ASTUnit from a source file, via a CompilerInvocation
+ /// Create an ASTUnit from a source file, via a CompilerInvocation
/// object, by invoking the optionally provided ASTFrontendAction.
///
/// \param CI - The compiler invocation to use; it must have exactly one input
@@ -782,14 +816,16 @@ public:
TranslationUnitKind TUKind = TU_Complete,
bool CacheCodeCompletionResults = false,
bool IncludeBriefCommentsInCodeCompletion = false,
- bool AllowPCHWithCompilerErrors = false, bool SkipFunctionBodies = false,
- bool SingleFileParse = false,
- bool UserFilesAreVolatile = false, bool ForSerialization = false,
+ bool AllowPCHWithCompilerErrors = false,
+ SkipFunctionBodiesScope SkipFunctionBodies =
+ SkipFunctionBodiesScope::None,
+ bool SingleFileParse = false, bool UserFilesAreVolatile = false,
+ bool ForSerialization = false,
llvm::Optional<StringRef> ModuleFormat = llvm::None,
std::unique_ptr<ASTUnit> *ErrAST = nullptr,
IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);
- /// \brief Reparse the source files using the same command-line options that
+ /// Reparse the source files using the same command-line options that
/// were originally used to produce this translation unit.
///
/// \param VFS - A vfs::FileSystem to be used for all file accesses. Note that
@@ -804,12 +840,12 @@ public:
ArrayRef<RemappedFile> RemappedFiles = None,
IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);
- /// \brief Free data that will be re-generated on the next parse.
+ /// Free data that will be re-generated on the next parse.
///
/// Preamble-related data is not affected.
void ResetForParse();
- /// \brief Perform code completion at the given file, line, and
+ /// Perform code completion at the given file, line, and
/// column within this translation unit.
///
/// \param File The file in which code completion will occur.
@@ -839,13 +875,13 @@ public:
SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers);
- /// \brief Save this translation unit to a file with the given name.
+ /// Save this translation unit to a file with the given name.
///
/// \returns true if there was a file error or false if the save was
/// successful.
bool Save(StringRef File);
- /// \brief Serialize this translation unit with the given output stream.
+ /// Serialize this translation unit with the given output stream.
///
/// \returns True if an error occurred, false otherwise.
bool serialize(raw_ostream &OS);
@@ -853,4 +889,4 @@ public:
} // namespace clang
-#endif
+#endif // LLVM_CLANG_FRONTEND_ASTUNIT_H
diff --git a/include/clang/Frontend/ChainedDiagnosticConsumer.h b/include/clang/Frontend/ChainedDiagnosticConsumer.h
index eb33273c2fb3f..04c6077dc35e7 100644
--- a/include/clang/Frontend/ChainedDiagnosticConsumer.h
+++ b/include/clang/Frontend/ChainedDiagnosticConsumer.h
@@ -32,7 +32,7 @@ public:
: OwningPrimary(std::move(Primary)), Primary(OwningPrimary.get()),
Secondary(std::move(Secondary)) {}
- /// \brief Construct without taking ownership of \c Primary.
+ /// Construct without taking ownership of \c Primary.
ChainedDiagnosticConsumer(DiagnosticConsumer *Primary,
std::unique_ptr<DiagnosticConsumer> Secondary)
: Primary(Primary), Secondary(std::move(Secondary)) {}
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index bb91cf5f742b7..a7e71f7ac0167 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -38,10 +38,12 @@ CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) o
CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink
CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
CODEGENOPT(Backchain , 1, 0) ///< -mbackchain
+CODEGENOPT(ControlFlowGuard , 1, 0) ///< -cfguard
CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files.
CODEGENOPT(CoverageNoFunctionNamesInData, 1, 0) ///< Do not include function names in GCDA files.
CODEGENOPT(CoverageExitBlockBeforeBody, 1, 0) ///< Whether to emit the exit block before the body blocks in GCNO files.
CODEGENOPT(CXAAtExit , 1, 1) ///< Use __cxa_atexit for calling destructors.
+CODEGENOPT(RegisterGlobalDtorsWithAtExit, 1, 1) ///< Use atexit or __cxa_atexit to register global destructors.
CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker
///< aliases to base ctors when possible.
CODEGENOPT(DataSections , 1, 0) ///< Set when -fdata-sections is enabled.
@@ -61,15 +63,19 @@ CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new
///< pass manager.
CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled.
CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls.
+CODEGENOPT(NoEscapingBlockTailCalls, 1, 0) ///< Do not emit tail calls from
+ ///< escaping blocks.
CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what
///< Decl* various IR entities came from.
///< Only useful when running CodeGen as a
///< subroutine.
+CODEGENOPT(EmitVersionIdentMetadata , 1, 1) ///< Emit compiler version metadata.
CODEGENOPT(EmitGcovArcs , 1, 0) ///< Emit coverage data files, aka. GCDA.
CODEGENOPT(EmitGcovNotes , 1, 0) ///< Emit coverage "notes" files, aka GCNO.
CODEGENOPT(EmitOpenCLArgMetadata , 1, 0) ///< Emit OpenCL kernel arg metadata.
-CODEGENOPT(EmulatedTLS , 1, 0) ///< Set when -femulated-tls is enabled.
-/// \brief Embed Bitcode mode (off/all/bitcode/marker).
+CODEGENOPT(EmulatedTLS , 1, 0) ///< Set by default or -f[no-]emulated-tls.
+CODEGENOPT(ExplicitEmulatedTLS , 1, 0) ///< Set if -f[no-]emulated-tls is used.
+/// Embed Bitcode mode (off/all/bitcode/marker).
ENUM_CODEGENOPT(EmbedBitcode, EmbedBitcodeKind, 2, Embed_Off)
CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
///< are required.
@@ -80,13 +86,20 @@ CODEGENOPT(InstrumentFunctionsAfterInlining , 1, 0) ///< Set when
///< -finstrument-functions-after-inlining is enabled.
CODEGENOPT(InstrumentFunctionEntryBare , 1, 0) ///< Set when
///< -finstrument-function-entry-bare is enabled.
-
+CODEGENOPT(CFProtectionReturn , 1, 0) ///< if -fcf-protection is
+ ///< set to full or return.
+CODEGENOPT(CFProtectionBranch , 1, 0) ///< if -fcf-protection is
+ ///< set to full or branch.
CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
///< enabled.
+CODEGENOPT(StackSizeSection , 1, 0) ///< Set when -fstack-size-section is enabled.
///< Set when -fxray-always-emit-customevents is enabled.
CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)
+///< Set when -fxray-always-emit-typedevents is enabled.
+CODEGENOPT(XRayAlwaysEmitTypedEvents , 1, 0)
+
///< Set the minimum number of instructions in a function to determine selective
///< XRay instrumentation.
VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)
@@ -97,7 +110,7 @@ CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions t
///< be generated.
CODEGENOPT(PrepareForLTO , 1, 0) ///< Set when -flto is enabled on the
///< compile step.
-CODEGENOPT(EmitSummaryIndex, 1, 0) ///< Set when -flto=thin is enabled on the
+CODEGENOPT(PrepareForThinLTO , 1, 0) ///< Set when -flto=thin is enabled on the
///< compile step.
CODEGENOPT(LTOUnit, 1, 0) ///< Emit IR to support LTO unit features (CFI, whole
///< program vtable opt).
@@ -117,27 +130,32 @@ CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled.
CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled.
CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf.
CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero
+CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined.
CODEGENOPT(Reassociate , 1, 0) ///< Allow reassociation of FP math ops
CODEGENOPT(ReciprocalMath , 1, 0) ///< Allow FP divisions to be reassociated.
CODEGENOPT(NoTrappingMath , 1, 0) ///< Set when -fno-trapping-math is enabled.
CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN.
CODEGENOPT(FlushDenorm , 1, 0) ///< Allow FP denorm numbers to be flushed to zero
CODEGENOPT(CorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt
+
+/// When false, this attempts to generate code as if the result of an
+/// overflowing conversion matches the overflowing behavior of a target's native
+/// float-to-int conversion instructions.
+CODEGENOPT(StrictFloatCastOverflow, 1, 1)
+
+CODEGENOPT(UniformWGSize , 1, 0) ///< -cl-uniform-work-group-size
CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss.
-/// \brief Method of Objective-C dispatch to use.
+/// Method of Objective-C dispatch to use.
ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy)
CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is
///< enabled.
-/// A version of Clang that we should attempt to be ABI-compatible with.
-ENUM_CODEGENOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest)
-
VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
-/// \brief Choose profile instrumenation kind or no instrumentation.
+/// Choose profile instrumenation kind or no instrumentation.
ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 2, ProfileNone)
-/// \brief Choose profile kind for PGO use compilation.
+/// Choose profile kind for PGO use compilation.
ENUM_CODEGENOPT(ProfileUse, ProfileInstrKind, 2, ProfileNone)
CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping regions to
///< enable code coverage analysis.
@@ -154,6 +172,9 @@ CODEGENOPT(NewStructPathTBAA , 1, 0) ///< Whether or not to use enhanced struct-
CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.
CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection
///< in AddressSanitizer
+CODEGENOPT(SanitizeAddressPoisonClassMemberArrayNewCookie, 1,
+ 0) ///< Enable poisoning operator new[] which is not a replaceable
+ ///< global allocation function in AddressSanitizer
CODEGENOPT(SanitizeAddressGlobalsDeadStripping, 1, 0) ///< Enable linker dead stripping
///< of globals in AddressSanitizer
CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
@@ -218,6 +239,7 @@ VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack
///< alignment, if not 0.
VALUE_CODEGENOPT(StackProbeSize , 32, 4096) ///< Overrides default stack
///< probe size, even if 0.
+CODEGENOPT(NoStackArgProbe, 1, 0) ///< Set when -mno-stack-arg-probe is used
CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information
///< in debug info.
@@ -230,7 +252,7 @@ CODEGENOPT(DebugExplicitImport, 1, 0) ///< Whether or not debug info should
CODEGENOPT(EnableSplitDwarf, 1, 0) ///< Whether to enable split DWARF
CODEGENOPT(SplitDwarfInlining, 1, 1) ///< Whether to include inlining info in the
///< skeleton CU to allow for symbolication
- ///< of inline stack frames without .dwo files.
+ ///< of inline stack frames without .dwo files.
CODEGENOPT(DebugFwdTemplateParams, 1, 0) ///< Whether to emit complete
///< template parameter descriptions in
///< forward declarations (versus just
@@ -308,6 +330,16 @@ CODEGENOPT(GnuPubnames, 1, 0)
CODEGENOPT(NoPLT, 1, 0)
+/// Whether to embed source in DWARF debug line section.
+CODEGENOPT(EmbedSource, 1, 0)
+
+/// Whether to emit all vtables
+CODEGENOPT(ForceEmitVTables, 1, 0)
+
+/// Whether to emit an address-significance table into the object file.
+CODEGENOPT(Addrsig, 1, 0)
+
+
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
#undef VALUE_CODEGENOPT
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 6b8d2b935fdd2..a6d061acf0f4a 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -16,6 +16,8 @@
#include "clang/Basic/DebugInfoOptions.h"
#include "clang/Basic/Sanitizers.h"
+#include "clang/Basic/XRayInstr.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Regex.h"
#include "llvm/Target/TargetOptions.h"
#include <map>
@@ -25,7 +27,7 @@
namespace clang {
-/// \brief Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure
+/// Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure
/// that this large collection of bitfields is a trivial class type.
class CodeGenOptionsBase {
public:
@@ -167,7 +169,7 @@ public:
std::string SplitDwarfFile;
/// The name of the relocation model to use.
- std::string RelocationModel;
+ llvm::Reloc::Model RelocationModel;
/// The thread model to use
std::string ThreadModel;
@@ -176,9 +178,6 @@ public:
/// function instead of to trap instructions.
std::string TrapFuncName;
- /// A list of command-line options to forward to the LLVM backend.
- std::vector<std::string> BackendOptions;
-
/// A list of dependent libraries.
std::vector<std::string> DependentLibraries;
@@ -204,10 +203,12 @@ public:
/// the summary and module symbol table (and not, e.g. any debug metadata).
std::string ThinLinkBitcodeFile;
- /// A list of file names passed with -fcuda-include-gpubinary options to
- /// forward to CUDA runtime back-end for incorporating them into host-side
- /// object file.
- std::vector<std::string> CudaGpuBinaryFileNames;
+ /// Prefix to use for -save-temps output.
+ std::string SaveTempsFilePrefix;
+
+ /// Name of file passed with -fcuda-include-gpubinary option to forward to
+ /// CUDA runtime back-end for incorporating them into host-side object file.
+ std::string CudaGpuBinaryFileName;
/// The name of the file to which the backend should save YAML optimization
/// records.
@@ -248,7 +249,7 @@ public:
/// List of backend command-line options for -fembed-bitcode.
std::vector<uint8_t> CmdArgs;
- /// \brief A list of all -fno-builtin-* function names (e.g., memset).
+ /// A list of all -fno-builtin-* function names (e.g., memset).
std::vector<std::string> NoBuiltinFuncs;
std::vector<std::string> Reciprocals;
@@ -258,6 +259,9 @@ public:
/// registers.
std::string PreferVectorWidth;
+ /// Set of XRay instrumentation kinds to emit.
+ XRayInstrSet XRayInstrumentationBundle;
+
public:
// Define accessors/mutators for code generation options of enumeration type.
#define CODEGENOPT(Name, Bits, Default)
@@ -268,7 +272,7 @@ public:
CodeGenOptions();
- /// \brief Is this a libc/libm function that is no longer recognized as a
+ /// Is this a libc/libm function that is no longer recognized as a
/// builtin because a -fno-builtin-* option has been specified?
bool isNoBuiltinFunc(const char *Name) const;
@@ -276,22 +280,22 @@ public:
return NoBuiltinFuncs;
}
- /// \brief Check if Clang profile instrumenation is on.
+ /// Check if Clang profile instrumenation is on.
bool hasProfileClangInstr() const {
return getProfileInstr() == ProfileClangInstr;
}
- /// \brief Check if IR level profile instrumentation is on.
+ /// Check if IR level profile instrumentation is on.
bool hasProfileIRInstr() const {
return getProfileInstr() == ProfileIRInstr;
}
- /// \brief Check if Clang profile use is on.
+ /// Check if Clang profile use is on.
bool hasProfileClangUse() const {
return getProfileUse() == ProfileClangInstr;
}
- /// \brief Check if IR level profile use is on.
+ /// Check if IR level profile use is on.
bool hasProfileIRUse() const {
return getProfileUse() == ProfileIRInstr;
}
diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h
index f5c1e1a8a67d0..7ae98e079264f 100644
--- a/include/clang/Frontend/CommandLineSourceLoc.h
+++ b/include/clang/Frontend/CommandLineSourceLoc.h
@@ -21,7 +21,7 @@
namespace clang {
-/// \brief A source location that has been parsed on the command line.
+/// A source location that has been parsed on the command line.
struct ParsedSourceLocation {
std::string FileName;
unsigned Line;
@@ -101,7 +101,7 @@ struct ParsedSourceRange {
namespace llvm {
namespace cl {
- /// \brief Command-line option parser that parses source locations.
+ /// Command-line option parser that parses source locations.
///
/// Source locations are of the form filename:line:column.
template<>
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 90a9501475b52..977d1b2ed65f5 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -109,59 +109,59 @@ class CompilerInstance : public ModuleLoader {
/// The code completion consumer.
std::unique_ptr<CodeCompleteConsumer> CompletionConsumer;
- /// \brief The semantic analysis object.
+ /// The semantic analysis object.
std::unique_ptr<Sema> TheSema;
- /// \brief The frontend timer group.
+ /// The frontend timer group.
std::unique_ptr<llvm::TimerGroup> FrontendTimerGroup;
- /// \brief The frontend timer.
+ /// The frontend timer.
std::unique_ptr<llvm::Timer> FrontendTimer;
- /// \brief The ASTReader, if one exists.
+ /// The ASTReader, if one exists.
IntrusiveRefCntPtr<ASTReader> ModuleManager;
- /// \brief The module dependency collector for crashdumps
+ /// The module dependency collector for crashdumps
std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector;
- /// \brief The module provider.
+ /// The module provider.
std::shared_ptr<PCHContainerOperations> ThePCHContainerOperations;
- /// \brief The dependency file generator.
+ /// The dependency file generator.
std::unique_ptr<DependencyFileGenerator> TheDependencyFileGenerator;
std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors;
- /// \brief The set of top-level modules that has already been loaded,
+ /// The set of top-level modules that has already been loaded,
/// along with the module map
llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules;
- /// \brief The set of top-level modules that has already been built on the
+ /// The set of top-level modules that has already been built on the
/// fly as part of this overall compilation action.
std::map<std::string, std::string> BuiltModules;
/// Should we delete the BuiltModules when we're done?
bool DeleteBuiltModules = true;
- /// \brief The location of the module-import keyword for the last module
+ /// The location of the module-import keyword for the last module
/// import.
SourceLocation LastModuleImportLoc;
- /// \brief The result of the last module import.
+ /// The result of the last module import.
///
ModuleLoadResult LastModuleImportResult;
- /// \brief Whether we should (re)build the global module index once we
+ /// Whether we should (re)build the global module index once we
/// have finished with this translation unit.
bool BuildGlobalModuleIndex = false;
- /// \brief We have a full global module index, with all modules.
+ /// We have a full global module index, with all modules.
bool HaveFullGlobalModuleIndex = false;
- /// \brief One or more modules failed to build.
+ /// One or more modules failed to build.
bool ModuleBuildFailed = false;
- /// \brief Holds information about the output file.
+ /// Holds information about the output file.
///
/// If TempFilename is not empty we must rename it to Filename at the end.
/// TempFilename may be empty and Filename non-empty if creating the temporary
@@ -183,6 +183,9 @@ class CompilerInstance : public ModuleLoader {
/// The list of active output files.
std::list<OutputFile> OutputFiles;
+ /// Force an output buffer.
+ std::unique_ptr<llvm::raw_pwrite_stream> OutputStream;
+
CompilerInstance(const CompilerInstance &) = delete;
void operator=(const CompilerInstance &) = delete;
public:
@@ -241,10 +244,10 @@ public:
/// setInvocation - Replace the current invocation.
void setInvocation(std::shared_ptr<CompilerInvocation> Value);
- /// \brief Indicates whether we should (re)build the global module index.
+ /// Indicates whether we should (re)build the global module index.
bool shouldBuildGlobalModuleIndex() const;
- /// \brief Set the flag indicating whether we should (re)build the global
+ /// Set the flag indicating whether we should (re)build the global
/// module index.
void setBuildGlobalModuleIndex(bool Build) {
BuildGlobalModuleIndex = Build;
@@ -387,7 +390,7 @@ public:
return *VirtualFileSystem;
}
- /// \brief Replace the current virtual file system.
+ /// Replace the current virtual file system.
///
/// \note Most clients should use setFileManager, which will implicitly reset
/// the virtual file system to the one contained in the file manager.
@@ -412,7 +415,7 @@ public:
FileMgr.resetWithoutRelease();
}
- /// \brief Replace the current file manager and virtual file system.
+ /// Replace the current file manager and virtual file system.
void setFileManager(FileManager *Value);
/// }
@@ -475,7 +478,7 @@ public:
/// setASTContext - Replace the current AST context.
void setASTContext(ASTContext *Value);
- /// \brief Replace the current Sema; the compiler instance takes ownership
+ /// Replace the current Sema; the compiler instance takes ownership
/// of S.
void setSema(Sema *S);
@@ -687,7 +690,7 @@ public:
Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column,
const CodeCompleteOptions &Opts, raw_ostream &OS);
- /// \brief Create the Sema object to be used for parsing.
+ /// Create the Sema object to be used for parsing.
void createSema(TranslationUnitKind TUKind,
CodeCompleteConsumer *CompletionConsumer);
@@ -773,6 +776,14 @@ public:
/// }
+ void setOutputStream(std::unique_ptr<llvm::raw_pwrite_stream> OutStream) {
+ OutputStream = std::move(OutStream);
+ }
+
+ std::unique_ptr<llvm::raw_pwrite_stream> takeOutputStream() {
+ return std::move(OutputStream);
+ }
+
// Create module manager.
void createModuleManager();
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index 8c4c932190bc3..3d302051d2988 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -1,4 +1,4 @@
-//===-- CompilerInvocation.h - Compiler Invocation Helper Data --*- C++ -*-===//
+//===- CompilerInvocation.h - Compiler Invocation Helper Data ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,11 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
-#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
+#ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
+#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Frontend/DependencyOutputOptions.h"
@@ -21,25 +22,29 @@
#include "clang/Frontend/PreprocessorOutputOptions.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include <memory>
#include <string>
namespace llvm {
+
class Triple;
namespace opt {
+
class ArgList;
-}
-}
+
+} // namespace opt
+
+} // namespace llvm
namespace clang {
-class PreprocessorOptions;
+
+class DiagnosticsEngine;
class HeaderSearchOptions;
+class PreprocessorOptions;
class TargetOptions;
-class LangOptions;
-class CompilerInvocation;
-class DiagnosticsEngine;
-/// \brief Fill out Opts based on the options given in Args.
+/// Fill out Opts based on the options given in Args.
///
/// Args must have been created from the OptTable returned by
/// createCC1OptTable().
@@ -52,8 +57,6 @@ bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args,
bool DefaultShowOpt = true);
class CompilerInvocationBase {
- void operator=(const CompilerInvocationBase &) = delete;
-
public:
/// Options controlling the language variant.
std::shared_ptr<LangOptions> LangOpts;
@@ -71,24 +74,24 @@ public:
std::shared_ptr<PreprocessorOptions> PreprocessorOpts;
CompilerInvocationBase();
- ~CompilerInvocationBase();
-
CompilerInvocationBase(const CompilerInvocationBase &X);
+ CompilerInvocationBase &operator=(const CompilerInvocationBase &) = delete;
+ ~CompilerInvocationBase();
LangOptions *getLangOpts() { return LangOpts.get(); }
const LangOptions *getLangOpts() const { return LangOpts.get(); }
TargetOptions &getTargetOpts() { return *TargetOpts.get(); }
- const TargetOptions &getTargetOpts() const {
- return *TargetOpts.get();
- }
+ const TargetOptions &getTargetOpts() const { return *TargetOpts.get(); }
DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; }
HeaderSearchOptions &getHeaderSearchOpts() { return *HeaderSearchOpts; }
+
const HeaderSearchOptions &getHeaderSearchOpts() const {
return *HeaderSearchOpts;
}
+
std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() const {
return HeaderSearchOpts;
}
@@ -96,13 +99,15 @@ public:
std::shared_ptr<PreprocessorOptions> getPreprocessorOptsPtr() {
return PreprocessorOpts;
}
+
PreprocessorOptions &getPreprocessorOpts() { return *PreprocessorOpts; }
+
const PreprocessorOptions &getPreprocessorOpts() const {
return *PreprocessorOpts;
}
};
-/// \brief Helper class for holding the data necessary to invoke the compiler.
+/// Helper class for holding the data necessary to invoke the compiler.
///
/// This class is designed to represent an abstract "invocation" of the
/// compiler, including data such as the include paths, the code generation
@@ -134,7 +139,7 @@ public:
/// @name Utility Methods
/// @{
- /// \brief Create a compiler invocation from a list of input options.
+ /// Create a compiler invocation from a list of input options.
/// \returns true on success.
///
/// \param [out] Res - The resulting invocation.
@@ -146,7 +151,7 @@ public:
const char* const *ArgEnd,
DiagnosticsEngine &Diags);
- /// \brief Get the directory where the compiler headers
+ /// Get the directory where the compiler headers
/// reside, relative to the compiler binary (found by the passed in
/// arguments).
///
@@ -156,7 +161,7 @@ public:
/// executable), for finding the builtin compiler path.
static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
- /// \brief Set language defaults for the given input language and
+ /// Set language defaults for the given input language and
/// language standard in the given LangOptions object.
///
/// \param Opts - The LangOptions object to set up.
@@ -168,7 +173,7 @@ public:
const llvm::Triple &T, PreprocessorOptions &PPOpts,
LangStandard::Kind LangStd = LangStandard::lang_unspecified);
- /// \brief Retrieve a module hash string that is suitable for uniquely
+ /// Retrieve a module hash string that is suitable for uniquely
/// identifying the conditions under which the module was built.
std::string getModuleHash() const;
@@ -176,40 +181,35 @@ public:
/// @name Option Subgroups
/// @{
- AnalyzerOptionsRef getAnalyzerOpts() const {
- return AnalyzerOpts;
- }
+ AnalyzerOptionsRef getAnalyzerOpts() const { return AnalyzerOpts; }
MigratorOptions &getMigratorOpts() { return MigratorOpts; }
- const MigratorOptions &getMigratorOpts() const {
- return MigratorOpts;
- }
+ const MigratorOptions &getMigratorOpts() const { return MigratorOpts; }
CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
- const CodeGenOptions &getCodeGenOpts() const {
- return CodeGenOpts;
- }
+ const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }
DependencyOutputOptions &getDependencyOutputOpts() {
return DependencyOutputOpts;
}
+
const DependencyOutputOptions &getDependencyOutputOpts() const {
return DependencyOutputOpts;
}
FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
+
const FileSystemOptions &getFileSystemOpts() const {
return FileSystemOpts;
}
FrontendOptions &getFrontendOpts() { return FrontendOpts; }
- const FrontendOptions &getFrontendOpts() const {
- return FrontendOpts;
- }
+ const FrontendOptions &getFrontendOpts() const { return FrontendOpts; }
PreprocessorOutputOptions &getPreprocessorOutputOpts() {
return PreprocessorOutputOpts;
}
+
const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
return PreprocessorOutputOpts;
}
@@ -218,8 +218,10 @@ public:
};
namespace vfs {
- class FileSystem;
-}
+
+class FileSystem;
+
+} // namespace vfs
IntrusiveRefCntPtr<vfs::FileSystem>
createVFSFromCompilerInvocation(const CompilerInvocation &CI,
@@ -230,6 +232,6 @@ createVFSFromCompilerInvocation(const CompilerInvocation &CI,
DiagnosticsEngine &Diags,
IntrusiveRefCntPtr<vfs::FileSystem> BaseFS);
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h
index 0be36cd9aa6ea..f419d2643649d 100644
--- a/include/clang/Frontend/DependencyOutputOptions.h
+++ b/include/clang/Frontend/DependencyOutputOptions.h
@@ -15,6 +15,9 @@
namespace clang {
+/// ShowIncludesDestination - Destination for /showIncludes output.
+enum class ShowIncludesDestination { None, Stdout, Stderr };
+
/// DependencyOutputFormat - Format for the compiler dependency file.
enum class DependencyOutputFormat { Make, NMake };
@@ -28,11 +31,13 @@ public:
/// dependency, which can avoid some 'make'
/// problems.
unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
- unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info.
unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.
+ /// Destination of cl.exe style /showIncludes info.
+ ShowIncludesDestination ShowIncludesDest = ShowIncludesDestination::None;
+
/// The format for the dependency file.
- DependencyOutputFormat OutputFormat;
+ DependencyOutputFormat OutputFormat = DependencyOutputFormat::Make;
/// The file to write dependency output to.
std::string OutputFile;
@@ -53,22 +58,16 @@ public:
/// In /showIncludes mode, pretend the main TU is a header with this name.
std::string ShowIncludesPretendHeader;
- /// \brief The file to write GraphViz-formatted header dependencies to.
+ /// The file to write GraphViz-formatted header dependencies to.
std::string DOTOutputFile;
- /// \brief The directory to copy module dependencies to when collecting them.
+ /// The directory to copy module dependencies to when collecting them.
std::string ModuleDependencyOutputDir;
public:
- DependencyOutputOptions() {
- IncludeSystemHeaders = 0;
- ShowHeaderIncludes = 0;
- UsePhonyTargets = 0;
- AddMissingHeaderDeps = 0;
- PrintShowIncludes = 0;
- IncludeModuleFiles = 0;
- OutputFormat = DependencyOutputFormat::Make;
- }
+ DependencyOutputOptions()
+ : IncludeSystemHeaders(0), ShowHeaderIncludes(0), UsePhonyTargets(0),
+ AddMissingHeaderDeps(0), IncludeModuleFiles(0) {}
};
} // end namespace clang
diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h
index e453d7db624c2..191d32accf2ff 100644
--- a/include/clang/Frontend/DiagnosticRenderer.h
+++ b/include/clang/Frontend/DiagnosticRenderer.h
@@ -1,4 +1,4 @@
-//===--- DiagnosticRenderer.h - Diagnostic Pretty-Printing ------*- C++ -*-===//
+//===- DiagnosticRenderer.h - Diagnostic Pretty-Printing --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,20 +17,23 @@
#define LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringRef.h"
namespace clang {
-class DiagnosticOptions;
class LangOptions;
class SourceManager;
-typedef llvm::PointerUnion<const Diagnostic *,
- const StoredDiagnostic *> DiagOrStoredDiag;
+using DiagOrStoredDiag =
+ llvm::PointerUnion<const Diagnostic *, const StoredDiagnostic *>;
-/// \brief Class to encapsulate the logic for formatting a diagnostic message.
+/// Class to encapsulate the logic for formatting a diagnostic message.
///
/// Actual "printing" logic is implemented by subclasses.
///
@@ -47,24 +50,24 @@ protected:
const LangOptions &LangOpts;
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
- /// \brief The location of the previous diagnostic if known.
+ /// The location of the previous diagnostic if known.
///
/// This will be invalid in cases where there is no (known) previous
/// diagnostic location, or that location itself is invalid or comes from
/// a different source manager than SM.
SourceLocation LastLoc;
- /// \brief The location of the last include whose stack was printed if known.
+ /// The location of the last include whose stack was printed if known.
///
/// Same restriction as LastLoc essentially, but tracking include stack
/// root locations rather than diagnostic locations.
SourceLocation LastIncludeLoc;
- /// \brief The level of the last diagnostic emitted.
+ /// The level of the last diagnostic emitted.
///
/// The level of the last diagnostic emitted. Used to detect level changes
/// which change the amount of information displayed.
- DiagnosticsEngine::Level LastLevel;
+ DiagnosticsEngine::Level LastLevel = DiagnosticsEngine::Ignored;
DiagnosticRenderer(const LangOptions &LangOpts,
DiagnosticOptions *DiagOpts);
@@ -97,7 +100,6 @@ protected:
virtual void endDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) {}
-
private:
void emitBasicNote(StringRef Message);
void emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc,
@@ -116,7 +118,7 @@ private:
ArrayRef<FixItHint> Hints);
public:
- /// \brief Emit a diagnostic.
+ /// Emit a diagnostic.
///
/// This is the primary entry point for emitting diagnostic messages.
/// It handles formatting and rendering the message as well as any ancillary
@@ -142,7 +144,7 @@ class DiagnosticNoteRenderer : public DiagnosticRenderer {
public:
DiagnosticNoteRenderer(const LangOptions &LangOpts,
DiagnosticOptions *DiagOpts)
- : DiagnosticRenderer(LangOpts, DiagOpts) {}
+ : DiagnosticRenderer(LangOpts, DiagOpts) {}
~DiagnosticNoteRenderer() override;
@@ -156,5 +158,7 @@ public:
virtual void emitNote(FullSourceLoc Loc, StringRef Message) = 0;
};
-} // end clang namespace
-#endif
+
+} // namespace clang
+
+#endif // LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_H
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
index 7ae6173512a68..2a4077d34391e 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the clang::FrontendAction interface and various convenience
+/// Defines the clang::FrontendAction interface and various convenience
/// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction,
/// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction)
/// derived from it.
@@ -48,7 +48,7 @@ protected:
/// @name Implementation Action Interface
/// @{
- /// \brief Create the AST consumer object for this action, if supported.
+ /// Create the AST consumer object for this action, if supported.
///
/// This routine is called as part of BeginSourceFile(), which will
/// fail if the AST consumer cannot be created. This will not be called if the
@@ -64,7 +64,7 @@ protected:
virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) = 0;
- /// \brief Callback before starting processing a single input, giving the
+ /// Callback before starting processing a single input, giving the
/// opportunity to modify the CompilerInvocation or do some other action
/// before BeginSourceFileAction is called.
///
@@ -72,7 +72,7 @@ protected:
/// ExecuteAction() and EndSourceFileAction() will not be called.
virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
- /// \brief Callback at the start of processing a single input.
+ /// Callback at the start of processing a single input.
///
/// \return True on success; on failure ExecutionAction() and
/// EndSourceFileAction() will not be called.
@@ -80,20 +80,20 @@ protected:
return true;
}
- /// \brief Callback to run the program action, using the initialized
+ /// Callback to run the program action, using the initialized
/// compiler instance.
///
/// This is guaranteed to only be called between BeginSourceFileAction()
/// and EndSourceFileAction().
virtual void ExecuteAction() = 0;
- /// \brief Callback at the end of processing a single input.
+ /// Callback at the end of processing a single input.
///
/// This is guaranteed to only be called following a successful call to
/// BeginSourceFileAction (and BeginSourceFile).
virtual void EndSourceFileAction() {}
- /// \brief Callback at the end of processing a single input, to determine
+ /// Callback at the end of processing a single input, to determine
/// if the output files should be erased or not.
///
/// By default it returns true if a compiler error occurred.
@@ -158,39 +158,39 @@ public:
/// @name Supported Modes
/// @{
- /// \brief Is this action invoked on a model file?
+ /// Is this action invoked on a model file?
///
/// Model files are incomplete translation units that relies on type
/// information from another translation unit. Check ParseModelFileAction for
/// details.
virtual bool isModelParsingAction() const { return false; }
- /// \brief Does this action only use the preprocessor?
+ /// Does this action only use the preprocessor?
///
/// If so no AST context will be created and this action will be invalid
/// with AST file inputs.
virtual bool usesPreprocessorOnly() const = 0;
- /// \brief For AST-based actions, the kind of translation unit we're handling.
+ /// For AST-based actions, the kind of translation unit we're handling.
virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
- /// \brief Does this action support use with PCH?
+ /// Does this action support use with PCH?
virtual bool hasPCHSupport() const { return true; }
- /// \brief Does this action support use with AST files?
+ /// Does this action support use with AST files?
virtual bool hasASTFileSupport() const { return true; }
- /// \brief Does this action support use with IR files?
+ /// Does this action support use with IR files?
virtual bool hasIRSupport() const { return false; }
- /// \brief Does this action support use with code completion?
+ /// Does this action support use with code completion?
virtual bool hasCodeCompletionSupport() const { return false; }
/// @}
/// @name Public Action Interface
/// @{
- /// \brief Prepare the action for processing the input file \p Input.
+ /// Prepare the action for processing the input file \p Input.
///
/// This is run after the options and frontend have been initialized,
/// but prior to executing any per-file processing.
@@ -211,20 +211,20 @@ public:
/// be aborted and neither Execute() nor EndSourceFile() should be called.
bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input);
- /// \brief Set the source manager's main input file, and run the action.
+ /// Set the source manager's main input file, and run the action.
bool Execute();
- /// \brief Perform any per-file post processing, deallocate per-file
+ /// Perform any per-file post processing, deallocate per-file
/// objects, and run statistics and output file cleanup code.
void EndSourceFile();
/// @}
};
-/// \brief Abstract base class to use for AST consumer-based frontend actions.
+/// Abstract base class to use for AST consumer-based frontend actions.
class ASTFrontendAction : public FrontendAction {
protected:
- /// \brief Implement the ExecuteAction interface by running Sema on
+ /// Implement the ExecuteAction interface by running Sema on
/// the already-initialized AST consumer.
///
/// This will also take care of instantiating a code completion consumer if
@@ -242,7 +242,7 @@ public:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override = 0;
- /// \brief Parse the given plugin command line arguments.
+ /// Parse the given plugin command line arguments.
///
/// \param CI - The compiler instance, for use in reporting diagnostics.
/// \return True if the parsing succeeded; otherwise the plugin will be
@@ -257,7 +257,7 @@ public:
AddBeforeMainAction, ///< Execute the action before the main action
AddAfterMainAction ///< Execute the action after the main action
};
- /// \brief Get the action type for this plugin
+ /// Get the action type for this plugin
///
/// \return The action type. If the type is Cmdline then by default the
/// plugin does nothing and what it does is determined by the cc1
@@ -265,10 +265,10 @@ public:
virtual ActionType getActionType() { return Cmdline; }
};
-/// \brief Abstract base class to use for preprocessor-based frontend actions.
+/// Abstract base class to use for preprocessor-based frontend actions.
class PreprocessorFrontendAction : public FrontendAction {
protected:
- /// \brief Provide a default implementation which returns aborts;
+ /// Provide a default implementation which returns aborts;
/// this method should never be called by FrontendAction clients.
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override;
@@ -277,7 +277,7 @@ public:
bool usesPreprocessorOnly() const override { return true; }
};
-/// \brief A frontend action which simply wraps some other runtime-specified
+/// A frontend action which simply wraps some other runtime-specified
/// frontend action.
///
/// Deriving from this class allows an action to inject custom logic around
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index fa1529a3d65dc..20f1b3e11bdb7 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -35,6 +35,18 @@ public:
bool usesPreprocessorOnly() const override { return false; }
};
+class DumpCompilerOptionsAction : public FrontendAction {
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override {
+ return nullptr;
+ }
+
+ void ExecuteAction() override;
+
+public:
+ bool usesPreprocessorOnly() const override { return true; }
+};
+
//===----------------------------------------------------------------------===//
// AST Consumer Actions
//===----------------------------------------------------------------------===//
@@ -83,14 +95,14 @@ protected:
bool shouldEraseOutputFiles() override;
public:
- /// \brief Compute the AST consumer arguments that will be used to
+ /// Compute the AST consumer arguments that will be used to
/// create the PCHGenerator instance returned by CreateASTConsumer.
///
/// \returns false if an error occurred, true otherwise.
static bool ComputeASTConsumerArguments(CompilerInstance &CI,
std::string &Sysroot);
- /// \brief Creates file to write the PCH into and returns a stream to write it
+ /// Creates file to write the PCH into and returns a stream to write it
/// into. On error, returns null.
static std::unique_ptr<llvm::raw_pwrite_stream>
CreateOutputFile(CompilerInstance &CI, StringRef InFile,
@@ -140,7 +152,7 @@ public:
bool hasCodeCompletionSupport() const override { return true; }
};
-/// \brief Dump information about the given module file, to be used for
+/// Dump information about the given module file, to be used for
/// basic debugging and discovery.
class DumpModuleInfoAction : public ASTFrontendAction {
protected:
@@ -167,8 +179,16 @@ public:
bool hasCodeCompletionSupport() const override { return false; }
};
+class TemplightDumpAction : public ASTFrontendAction {
+protected:
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+
+ void ExecuteAction() override;
+};
+
/**
- * \brief Frontend action adaptor that merges ASTs together.
+ * Frontend action adaptor that merges ASTs together.
*
* This action takes an existing AST file and "merges" it into the AST
* context, producing a merged context. This action is an action
@@ -176,10 +196,10 @@ public:
* will consume the merged context.
*/
class ASTMergeAction : public FrontendAction {
- /// \brief The action that the merge action adapts.
+ /// The action that the merge action adapts.
std::unique_ptr<FrontendAction> AdaptedAction;
- /// \brief The set of AST files to merge.
+ /// The set of AST files to merge.
std::vector<std::string> ASTFiles;
protected:
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index 5192a3774cc1d..668df83274eb5 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -1,4 +1,4 @@
-//===--- FrontendOptions.h --------------------------------------*- C++ -*-===//
+//===- FrontendOptions.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,54 +14,127 @@
#include "clang/Serialization/ModuleFileExtension.h"
#include "clang/Sema/CodeCompleteOptions.h"
#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
namespace llvm {
+
class MemoryBuffer;
-}
+
+} // namespace llvm
namespace clang {
-class FileEntry;
namespace frontend {
- enum ActionKind {
- ASTDeclList, ///< Parse ASTs and list Decl nodes.
- ASTDump, ///< Parse ASTs and dump them.
- ASTPrint, ///< Parse ASTs and print them.
- ASTView, ///< Parse ASTs and view them in Graphviz.
- DumpRawTokens, ///< Dump out raw tokens.
- DumpTokens, ///< Dump out preprocessed tokens.
- EmitAssembly, ///< Emit a .s file.
- EmitBC, ///< Emit a .bc file.
- EmitHTML, ///< Translate input source into HTML.
- EmitLLVM, ///< Emit a .ll file.
- EmitLLVMOnly, ///< Generate LLVM IR, but do not emit anything.
- EmitCodeGenOnly, ///< Generate machine code, but don't emit anything.
- EmitObj, ///< Emit a .o file.
- FixIt, ///< Parse and apply any fixits to the source.
- GenerateModule, ///< Generate pre-compiled module from a module map.
- GenerateModuleInterface,///< Generate pre-compiled module from a C++ module
- ///< interface file.
- GeneratePCH, ///< Generate pre-compiled header.
- GeneratePTH, ///< Generate pre-tokenized header.
- InitOnly, ///< Only execute frontend initialization.
- ModuleFileInfo, ///< Dump information about a module file.
- VerifyPCH, ///< Load and verify that a PCH file is usable.
- ParseSyntaxOnly, ///< Parse and perform semantic analysis.
- PluginAction, ///< Run a plugin action, \see ActionName.
- PrintDeclContext, ///< Print DeclContext and their Decls.
- PrintPreamble, ///< Print the "preamble" of the input file
- PrintPreprocessedInput, ///< -E mode.
- RewriteMacros, ///< Expand macros but not \#includes.
- RewriteObjC, ///< ObjC->C Rewriter.
- RewriteTest, ///< Rewriter playground
- RunAnalysis, ///< Run one or more source code analyses.
- MigrateSource, ///< Run migrator.
- RunPreprocessorOnly ///< Just lex, no output.
- };
-}
+
+enum ActionKind {
+ /// Parse ASTs and list Decl nodes.
+ ASTDeclList,
+
+ /// Parse ASTs and dump them.
+ ASTDump,
+
+ /// Parse ASTs and print them.
+ ASTPrint,
+
+ /// Parse ASTs and view them in Graphviz.
+ ASTView,
+
+ /// Dump the compiler configuration.
+ DumpCompilerOptions,
+
+ /// Dump out raw tokens.
+ DumpRawTokens,
+
+ /// Dump out preprocessed tokens.
+ DumpTokens,
+
+ /// Emit a .s file.
+ EmitAssembly,
+
+ /// Emit a .bc file.
+ EmitBC,
+
+ /// Translate input source into HTML.
+ EmitHTML,
+
+ /// Emit a .ll file.
+ EmitLLVM,
+
+ /// Generate LLVM IR, but do not emit anything.
+ EmitLLVMOnly,
+
+ /// Generate machine code, but don't emit anything.
+ EmitCodeGenOnly,
+
+ /// Emit a .o file.
+ EmitObj,
+
+ /// Parse and apply any fixits to the source.
+ FixIt,
+
+ /// Generate pre-compiled module from a module map.
+ GenerateModule,
+
+ /// Generate pre-compiled module from a C++ module interface file.
+ GenerateModuleInterface,
+
+ /// Generate pre-compiled header.
+ GeneratePCH,
+
+ /// Generate pre-tokenized header.
+ GeneratePTH,
+
+ /// Only execute frontend initialization.
+ InitOnly,
+
+ /// Dump information about a module file.
+ ModuleFileInfo,
+
+ /// Load and verify that a PCH file is usable.
+ VerifyPCH,
+
+ /// Parse and perform semantic analysis.
+ ParseSyntaxOnly,
+
+ /// Run a plugin action, \see ActionName.
+ PluginAction,
+
+ /// Print DeclContext and their Decls.
+ PrintDeclContext,
+
+ /// Print the "preamble" of the input file
+ PrintPreamble,
+
+ /// -E mode.
+ PrintPreprocessedInput,
+
+ /// Expand macros but not \#includes.
+ RewriteMacros,
+
+ /// ObjC->C Rewriter.
+ RewriteObjC,
+
+ /// Rewriter playground
+ RewriteTest,
+
+ /// Run one or more source code analyses.
+ RunAnalysis,
+
+ /// Dump template instantiations
+ TemplightDump,
+
+ /// Run migrator.
+ MigrateSource,
+
+ /// Just lex, no output.
+ RunPreprocessorOnly
+};
+
+} // namespace frontend
/// The kind of a file that we've been handed as an input.
class InputKind {
@@ -91,6 +164,7 @@ public:
OpenCL,
CUDA,
RenderScript,
+ HIP,
///@}
};
@@ -118,14 +192,15 @@ public:
InputKind getPreprocessed() const {
return InputKind(getLanguage(), getFormat(), true);
}
+
InputKind withFormat(Format F) const {
return InputKind(getLanguage(), F, isPreprocessed());
}
};
-/// \brief An input file for the front end.
+/// An input file for the front end.
class FrontendInputFile {
- /// \brief The file name, or "-" to read from standard input.
+ /// The file name, or "-" to read from standard input.
std::string File;
/// The input, if it comes from a buffer rather than a file. This object
@@ -133,19 +208,19 @@ class FrontendInputFile {
/// that it outlives any users.
llvm::MemoryBuffer *Buffer = nullptr;
- /// \brief The kind of input, e.g., C source, AST file, LLVM IR.
+ /// The kind of input, e.g., C source, AST file, LLVM IR.
InputKind Kind;
- /// \brief Whether we're dealing with a 'system' input (vs. a 'user' input).
+ /// Whether we're dealing with a 'system' input (vs. a 'user' input).
bool IsSystem = false;
public:
- FrontendInputFile() { }
+ FrontendInputFile() = default;
FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)
- : File(File.str()), Kind(Kind), IsSystem(IsSystem) { }
+ : File(File.str()), Kind(Kind), IsSystem(IsSystem) {}
FrontendInputFile(llvm::MemoryBuffer *Buffer, InputKind Kind,
bool IsSystem = false)
- : Buffer(Buffer), Kind(Kind), IsSystem(IsSystem) { }
+ : Buffer(Buffer), Kind(Kind), IsSystem(IsSystem) {}
InputKind getKind() const { return Kind; }
bool isSystem() const { return IsSystem; }
@@ -159,6 +234,7 @@ public:
assert(isFile());
return File;
}
+
llvm::MemoryBuffer *getBuffer() const {
assert(isBuffer());
return Buffer;
@@ -168,43 +244,67 @@ public:
/// FrontendOptions - Options for controlling the behavior of the frontend.
class FrontendOptions {
public:
- unsigned DisableFree : 1; ///< Disable memory freeing on exit.
- unsigned RelocatablePCH : 1; ///< When generating PCH files,
- /// instruct the AST writer to create
- /// relocatable PCH files.
- unsigned ShowHelp : 1; ///< Show the -help text.
- unsigned ShowStats : 1; ///< Show frontend performance
- /// metrics and statistics.
- unsigned ShowTimers : 1; ///< Show timers for individual
- /// actions.
- unsigned ShowVersion : 1; ///< Show the -version text.
- unsigned FixWhatYouCan : 1; ///< Apply fixes even if there are
- /// unfixable errors.
- unsigned FixOnlyWarnings : 1; ///< Apply fixes only for warnings.
- unsigned FixAndRecompile : 1; ///< Apply fixes and recompile.
- unsigned FixToTemporaries : 1; ///< Apply fixes to temporary files.
- unsigned ARCMTMigrateEmitARCErrors : 1; /// Emit ARC errors even if the
- /// migrator can fix them
- unsigned SkipFunctionBodies : 1; ///< Skip over function bodies to
- /// speed up parsing in cases you do
- /// not need them (e.g. with code
- /// completion).
- unsigned UseGlobalModuleIndex : 1; ///< Whether we can use the
- ///< global module index if available.
- unsigned GenerateGlobalModuleIndex : 1; ///< Whether we can generate the
- ///< global module index if needed.
- unsigned ASTDumpDecls : 1; ///< Whether we include declaration
- ///< dumps in AST dumps.
- unsigned ASTDumpAll : 1; ///< Whether we deserialize all decls
- ///< when forming AST dumps.
- unsigned ASTDumpLookups : 1; ///< Whether we include lookup table
- ///< dumps in AST dumps.
- unsigned BuildingImplicitModule : 1; ///< Whether we are performing an
- ///< implicit module build.
- unsigned ModulesEmbedAllFiles : 1; ///< Whether we should embed all used
- ///< files into the PCM file.
- unsigned IncludeTimestamps : 1; ///< Whether timestamps should be
- ///< written to the produced PCH file.
+ /// Disable memory freeing on exit.
+ unsigned DisableFree : 1;
+
+ /// When generating PCH files, instruct the AST writer to create relocatable
+ /// PCH files.
+ unsigned RelocatablePCH : 1;
+
+ /// Show the -help text.
+ unsigned ShowHelp : 1;
+
+ /// Show frontend performance metrics and statistics.
+ unsigned ShowStats : 1;
+
+ /// Show timers for individual actions.
+ unsigned ShowTimers : 1;
+
+ /// Show the -version text.
+ unsigned ShowVersion : 1;
+
+ /// Apply fixes even if there are unfixable errors.
+ unsigned FixWhatYouCan : 1;
+
+ /// Apply fixes only for warnings.
+ unsigned FixOnlyWarnings : 1;
+
+ /// Apply fixes and recompile.
+ unsigned FixAndRecompile : 1;
+
+ /// Apply fixes to temporary files.
+ unsigned FixToTemporaries : 1;
+
+ /// Emit ARC errors even if the migrator can fix them.
+ unsigned ARCMTMigrateEmitARCErrors : 1;
+
+ /// Skip over function bodies to speed up parsing in cases you do not need
+ /// them (e.g. with code completion).
+ unsigned SkipFunctionBodies : 1;
+
+ /// Whether we can use the global module index if available.
+ unsigned UseGlobalModuleIndex : 1;
+
+ /// Whether we can generate the global module index if needed.
+ unsigned GenerateGlobalModuleIndex : 1;
+
+ /// Whether we include declaration dumps in AST dumps.
+ unsigned ASTDumpDecls : 1;
+
+ /// Whether we deserialize all decls when forming AST dumps.
+ unsigned ASTDumpAll : 1;
+
+ /// Whether we include lookup table dumps in AST dumps.
+ unsigned ASTDumpLookups : 1;
+
+ /// Whether we are performing an implicit module build.
+ unsigned BuildingImplicitModule : 1;
+
+ /// Whether we should embed all used files into the PCM file.
+ unsigned ModulesEmbedAllFiles : 1;
+
+ /// Whether timestamps should be written to the produced PCH file.
+ unsigned IncludeTimestamps : 1;
CodeCompleteOptions CodeCompleteOpts;
@@ -213,38 +313,53 @@ public:
ARCMT_Check,
ARCMT_Modify,
ARCMT_Migrate
- } ARCMTAction;
+ } ARCMTAction = ARCMT_None;
enum {
ObjCMT_None = 0,
- /// \brief Enable migration to modern ObjC literals.
+
+ /// Enable migration to modern ObjC literals.
ObjCMT_Literals = 0x1,
- /// \brief Enable migration to modern ObjC subscripting.
+
+ /// Enable migration to modern ObjC subscripting.
ObjCMT_Subscripting = 0x2,
- /// \brief Enable migration to modern ObjC readonly property.
+
+ /// Enable migration to modern ObjC readonly property.
ObjCMT_ReadonlyProperty = 0x4,
- /// \brief Enable migration to modern ObjC readwrite property.
+
+ /// Enable migration to modern ObjC readwrite property.
ObjCMT_ReadwriteProperty = 0x8,
- /// \brief Enable migration to modern ObjC property.
+
+ /// Enable migration to modern ObjC property.
ObjCMT_Property = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty),
- /// \brief Enable annotation of ObjCMethods of all kinds.
+
+ /// Enable annotation of ObjCMethods of all kinds.
ObjCMT_Annotation = 0x10,
- /// \brief Enable migration of ObjC methods to 'instancetype'.
+
+ /// Enable migration of ObjC methods to 'instancetype'.
ObjCMT_Instancetype = 0x20,
- /// \brief Enable migration to NS_ENUM/NS_OPTIONS macros.
+
+ /// Enable migration to NS_ENUM/NS_OPTIONS macros.
ObjCMT_NsMacros = 0x40,
- /// \brief Enable migration to add conforming protocols.
+
+ /// Enable migration to add conforming protocols.
ObjCMT_ProtocolConformance = 0x80,
- /// \brief prefer 'atomic' property over 'nonatomic'.
+
+ /// prefer 'atomic' property over 'nonatomic'.
ObjCMT_AtomicProperty = 0x100,
- /// \brief annotate property with NS_RETURNS_INNER_POINTER
+
+ /// annotate property with NS_RETURNS_INNER_POINTER
ObjCMT_ReturnsInnerPointerProperty = 0x200,
- /// \brief use NS_NONATOMIC_IOSONLY for property 'atomic' attribute
+
+ /// use NS_NONATOMIC_IOSONLY for property 'atomic' attribute
ObjCMT_NsAtomicIOSOnlyProperty = 0x400,
- /// \brief Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods.
+
+ /// Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods.
ObjCMT_DesignatedInitializer = 0x800,
- /// \brief Enable converting setter/getter expressions to property-dot syntx.
+
+ /// Enable converting setter/getter expressions to property-dot syntx.
ObjCMT_PropertyDotSyntax = 0x1000,
+
ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty |
ObjCMT_Annotation | ObjCMT_Instancetype |
ObjCMT_NsMacros | ObjCMT_ProtocolConformance |
@@ -253,7 +368,7 @@ public:
ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting |
ObjCMT_MigrateDecls | ObjCMT_PropertyDotSyntax)
};
- unsigned ObjCMTAction;
+ unsigned ObjCMTAction = ObjCMT_None;
std::string ObjCMTWhiteListPath;
std::string MTMigrateDir;
@@ -279,7 +394,7 @@ public:
ParsedSourceLocation CodeCompletionAt;
/// The frontend action to perform.
- frontend::ActionKind ProgramAction;
+ frontend::ActionKind ProgramAction = frontend::ParseSyntaxOnly;
/// The name of the action to run when using a plugin action.
std::string ActionName;
@@ -296,49 +411,43 @@ public:
/// The list of module file extensions.
std::vector<std::shared_ptr<ModuleFileExtension>> ModuleFileExtensions;
- /// \brief The list of module map files to load before processing the input.
+ /// The list of module map files to load before processing the input.
std::vector<std::string> ModuleMapFiles;
- /// \brief The list of additional prebuilt module files to load before
+ /// The list of additional prebuilt module files to load before
/// processing the input.
std::vector<std::string> ModuleFiles;
- /// \brief The list of files to embed into the compiled module file.
+ /// The list of files to embed into the compiled module file.
std::vector<std::string> ModulesEmbedFiles;
- /// \brief The list of AST files to merge.
+ /// The list of AST files to merge.
std::vector<std::string> ASTMergeFiles;
- /// \brief A list of arguments to forward to LLVM's option processing; this
+ /// A list of arguments to forward to LLVM's option processing; this
/// should only be used for debugging and experimental features.
std::vector<std::string> LLVMArgs;
- /// \brief File name of the file that will provide record layouts
+ /// File name of the file that will provide record layouts
/// (in the format produced by -fdump-record-layouts).
std::string OverrideRecordLayoutsFile;
- /// \brief Auxiliary triple for CUDA compilation.
+ /// Auxiliary triple for CUDA compilation.
std::string AuxTriple;
- /// \brief If non-empty, search the pch input file as if it was a header
- /// included by this file.
- std::string FindPchSource;
-
/// Filename to write statistics to.
std::string StatsFile;
public:
- FrontendOptions() :
- DisableFree(false), RelocatablePCH(false), ShowHelp(false),
- ShowStats(false), ShowTimers(false), ShowVersion(false),
- FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false),
- FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false),
- SkipFunctionBodies(false), UseGlobalModuleIndex(true),
- GenerateGlobalModuleIndex(true), ASTDumpDecls(false), ASTDumpLookups(false),
- BuildingImplicitModule(false), ModulesEmbedAllFiles(false),
- IncludeTimestamps(true), ARCMTAction(ARCMT_None),
- ObjCMTAction(ObjCMT_None), ProgramAction(frontend::ParseSyntaxOnly)
- {}
+ FrontendOptions()
+ : DisableFree(false), RelocatablePCH(false), ShowHelp(false),
+ ShowStats(false), ShowTimers(false), ShowVersion(false),
+ FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false),
+ FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false),
+ SkipFunctionBodies(false), UseGlobalModuleIndex(true),
+ GenerateGlobalModuleIndex(true), ASTDumpDecls(false),
+ ASTDumpLookups(false), BuildingImplicitModule(false),
+ ModulesEmbedAllFiles(false), IncludeTimestamps(true) {}
/// getInputKindForExtension - Return the appropriate input kind for a file
/// extension. For example, "c" would return InputKind::C.
@@ -348,6 +457,6 @@ public:
static InputKind getInputKindForExtension(StringRef Extension);
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h
index 9d7ee08d95d4b..9a85e89d905d8 100644
--- a/include/clang/Frontend/FrontendPluginRegistry.h
+++ b/include/clang/Frontend/FrontendPluginRegistry.h
@@ -1,4 +1,4 @@
-//===-- FrontendAction.h - Pluggable Frontend Action Interface --*- C++ -*-===//
+//===- FrontendPluginRegistry.h ---------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,6 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// Pluggable Frontend Action Interface
+//
+//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H
#define LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H
@@ -16,8 +20,8 @@
namespace clang {
/// The frontend plugin registry.
-typedef llvm::Registry<PluginASTAction> FrontendPluginRegistry;
+using FrontendPluginRegistry = llvm::Registry<PluginASTAction>;
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
index e7a081dc2aa76..1e895d785d15c 100644
--- a/include/clang/Frontend/LangStandards.def
+++ b/include/clang/Frontend/LangStandards.def
@@ -155,6 +155,9 @@ LANGSTANDARD(opencl12, "cl1.2",
LANGSTANDARD(opencl20, "cl2.0",
OpenCL, "OpenCL 2.0",
LineComment | C99 | Digraphs | HexFloat | OpenCL)
+LANGSTANDARD(openclcpp, "c++",
+ OpenCL, "OpenCL C++ 1.0",
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs | OpenCL)
LANGSTANDARD_ALIAS_DEPR(opencl10, "CL")
LANGSTANDARD_ALIAS_DEPR(opencl11, "CL1.1")
@@ -165,6 +168,10 @@ LANGSTANDARD_ALIAS_DEPR(opencl20, "CL2.0")
LANGSTANDARD(cuda, "cuda", CUDA, "NVIDIA CUDA(tm)",
LineComment | CPlusPlus | Digraphs)
+// HIP
+LANGSTANDARD(hip, "hip", HIP, "HIP",
+ LineComment | CPlusPlus | Digraphs)
+
#undef LANGSTANDARD
#undef LANGSTANDARD_ALIAS
#undef LANGSTANDARD_ALIAS_DEPR
diff --git a/include/clang/Frontend/LayoutOverrideSource.h b/include/clang/Frontend/LayoutOverrideSource.h
index 16d032b7dd72c..0b7f7dc7a7d67 100644
--- a/include/clang/Frontend/LayoutOverrideSource.h
+++ b/include/clang/Frontend/LayoutOverrideSource.h
@@ -1,4 +1,4 @@
-//===--- LayoutOverrideSource.h --Override Record Layouts -----------------===//
+//===--- LayoutOverrideSource.h --Override Record Layouts -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,36 +16,36 @@
#include "llvm/ADT/StringRef.h"
namespace clang {
- /// \brief An external AST source that overrides the layout of
+ /// An external AST source that overrides the layout of
/// a specified set of record types.
///
/// This class is used only for testing the ability of external AST sources
/// to override the layout of record types. Its input is the output format
/// of the command-line argument -fdump-record-layouts.
class LayoutOverrideSource : public ExternalASTSource {
- /// \brief The layout of a given record.
+ /// The layout of a given record.
struct Layout {
- /// \brief The size of the record.
+ /// The size of the record.
uint64_t Size;
- /// \brief The alignment of the record.
+ /// The alignment of the record.
uint64_t Align;
- /// \brief The offsets of the fields, in source order.
+ /// The offsets of the fields, in source order.
SmallVector<uint64_t, 8> FieldOffsets;
};
- /// \brief The set of layouts that will be overridden.
+ /// The set of layouts that will be overridden.
llvm::StringMap<Layout> Layouts;
public:
- /// \brief Create a new AST source that overrides the layout of some
+ /// Create a new AST source that overrides the layout of some
/// set of record types.
///
/// The file is the result of passing -fdump-record-layouts to a file.
explicit LayoutOverrideSource(StringRef Filename);
- /// \brief If this particular record type has an overridden layout,
+ /// If this particular record type has an overridden layout,
/// return that layout.
bool
layoutRecordType(const RecordDecl *Record,
@@ -55,7 +55,7 @@ namespace clang {
llvm::DenseMap<const CXXRecordDecl *,
CharUnits> &VirtualBaseOffsets) override;
- /// \brief Dump the overridden layouts.
+ /// Dump the overridden layouts.
void dump();
};
}
diff --git a/include/clang/Frontend/MultiplexConsumer.h b/include/clang/Frontend/MultiplexConsumer.h
index d13565c27bc33..214fefb219cde 100644
--- a/include/clang/Frontend/MultiplexConsumer.h
+++ b/include/clang/Frontend/MultiplexConsumer.h
@@ -17,13 +17,34 @@
#include "clang/Basic/LLVM.h"
#include "clang/Sema/SemaConsumer.h"
+#include "clang/Serialization/ASTDeserializationListener.h"
#include <memory>
#include <vector>
namespace clang {
class MultiplexASTMutationListener;
-class MultiplexASTDeserializationListener;
+
+// This ASTDeserializationListener forwards its notifications to a set of
+// child listeners.
+class MultiplexASTDeserializationListener : public ASTDeserializationListener {
+public:
+ // Does NOT take ownership of the elements in L.
+ MultiplexASTDeserializationListener(
+ const std::vector<ASTDeserializationListener *> &L);
+ void ReaderInitialized(ASTReader *Reader) override;
+ void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override;
+ void MacroRead(serialization::MacroID ID, MacroInfo *MI) override;
+ void TypeRead(serialization::TypeIdx Idx, QualType T) override;
+ void DeclRead(serialization::DeclID ID, const Decl *D) override;
+ void SelectorRead(serialization::SelectorID iD, Selector Sel) override;
+ void MacroDefinitionRead(serialization::PreprocessedEntityID,
+ MacroDefinitionRecord *MD) override;
+ void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override;
+
+private:
+ std::vector<ASTDeserializationListener *> Listeners;
+};
// Has a list of ASTConsumers and calls each of them. Owns its children.
class MultiplexConsumer : public SemaConsumer {
diff --git a/include/clang/Frontend/PrecompiledPreamble.h b/include/clang/Frontend/PrecompiledPreamble.h
index 130fe60704a74..6abdbe3a1e1b1 100644
--- a/include/clang/Frontend/PrecompiledPreamble.h
+++ b/include/clang/Frontend/PrecompiledPreamble.h
@@ -38,7 +38,7 @@ class CompilerInvocation;
class DeclGroupRef;
class PCHContainerOperations;
-/// \brief Runs lexer to compute suggested preamble bounds.
+/// Runs lexer to compute suggested preamble bounds.
PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts,
llvm::MemoryBuffer *Buffer,
unsigned MaxLines);
@@ -53,7 +53,7 @@ class PrecompiledPreamble {
struct PreambleFileHash;
public:
- /// \brief Try to build PrecompiledPreamble for \p Invocation. See
+ /// Try to build PrecompiledPreamble for \p Invocation. See
/// BuildPreambleError for possible error codes.
///
/// \param Invocation Original CompilerInvocation with options to compile the
@@ -104,14 +104,22 @@ public:
/// Changes options inside \p CI to use PCH from this preamble. Also remaps
/// main file to \p MainFileBuffer and updates \p VFS to ensure the preamble
/// is accessible.
- /// For in-memory preambles, PrecompiledPreamble instance continues to own
- /// the MemoryBuffer with the Preamble after this method returns. The caller
- /// is reponsible for making sure the PrecompiledPreamble instance outlives
- /// the compiler run and the AST that will be using the PCH.
+ /// Requires that CanReuse() is true.
+ /// For in-memory preambles, PrecompiledPreamble instance continues to own the
+ /// MemoryBuffer with the Preamble after this method returns. The caller is
+ /// responsible for making sure the PrecompiledPreamble instance outlives the
+ /// compiler run and the AST that will be using the PCH.
void AddImplicitPreamble(CompilerInvocation &CI,
IntrusiveRefCntPtr<vfs::FileSystem> &VFS,
llvm::MemoryBuffer *MainFileBuffer) const;
+ /// Configure \p CI to use this preamble.
+ /// Like AddImplicitPreamble, but doesn't assume CanReuse() is true.
+ /// If this preamble does not match the file, it may parse differently.
+ void OverridePreamble(CompilerInvocation &CI,
+ IntrusiveRefCntPtr<vfs::FileSystem> &VFS,
+ llvm::MemoryBuffer *MainFileBuffer) const;
+
private:
PrecompiledPreamble(PCHStorage Storage, std::vector<char> PreambleBytes,
bool PreambleEndsAtStartOfLine,
@@ -222,6 +230,12 @@ private:
}
};
+ /// Helper function to set up PCH for the preamble into \p CI and \p VFS to
+ /// with the specified \p Bounds.
+ void configurePreamble(PreambleBounds Bounds, CompilerInvocation &CI,
+ IntrusiveRefCntPtr<vfs::FileSystem> &VFS,
+ llvm::MemoryBuffer *MainFileBuffer) const;
+
/// Sets up the PreprocessorOptions and changes VFS, so that PCH stored in \p
/// Storage is accessible to clang. This method is an implementation detail of
/// AddImplicitPreamble.
@@ -275,7 +289,6 @@ enum class BuildPreambleError {
PreambleIsEmpty = 1,
CouldntCreateTempFile,
CouldntCreateTargetInfo,
- CouldntCreateVFSOverlay,
BeginSourceFileFailed,
CouldntEmitPCH
};
diff --git a/include/clang/Frontend/SerializedDiagnosticPrinter.h b/include/clang/Frontend/SerializedDiagnosticPrinter.h
index 4c57e9d404f0f..dc68c32fb15ae 100644
--- a/include/clang/Frontend/SerializedDiagnosticPrinter.h
+++ b/include/clang/Frontend/SerializedDiagnosticPrinter.h
@@ -1,4 +1,4 @@
-//===--- SerializedDiagnosticPrinter.h - Serializer for diagnostics -------===//
+//===--- SerializedDiagnosticPrinter.h - Diagnostics serializer -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -25,11 +25,11 @@ class DiagnosticOptions;
namespace serialized_diags {
-/// \brief Returns a DiagnosticConsumer that serializes diagnostics to
+/// Returns a DiagnosticConsumer that serializes diagnostics to
/// a bitcode file.
///
/// The created DiagnosticConsumer is designed for quick and lightweight
-/// transfer of of diagnostics to the enclosing build system (e.g., an IDE).
+/// transfer of diagnostics to the enclosing build system (e.g., an IDE).
/// This allows wrapper tools for Clang to get diagnostics from Clang
/// (via libclang) without needing to parse Clang's command line output.
///
diff --git a/include/clang/Frontend/SerializedDiagnosticReader.h b/include/clang/Frontend/SerializedDiagnosticReader.h
index 07479844d4654..595bdf1f4d7ab 100644
--- a/include/clang/Frontend/SerializedDiagnosticReader.h
+++ b/include/clang/Frontend/SerializedDiagnosticReader.h
@@ -1,4 +1,4 @@
-//===--- SerializedDiagnosticReader.h - Reads diagnostics -------*- C++ -*-===//
+//===- SerializedDiagnosticReader.h - Reads diagnostics ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,12 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_FRONTEND_SERIALIZED_DIAGNOSTIC_READER_H_
-#define LLVM_CLANG_FRONTEND_SERIALIZED_DIAGNOSTIC_READER_H_
+#ifndef LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICREADER_H
+#define LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICREADER_H
#include "clang/Basic/LLVM.h"
#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorOr.h"
+#include <system_error>
namespace clang {
namespace serialized_diags {
@@ -41,90 +43,97 @@ inline std::error_code make_error_code(SDError E) {
return std::error_code(static_cast<int>(E), SDErrorCategory());
}
-/// \brief A location that is represented in the serialized diagnostics.
+/// A location that is represented in the serialized diagnostics.
struct Location {
unsigned FileID;
unsigned Line;
unsigned Col;
unsigned Offset;
+
Location(unsigned FileID, unsigned Line, unsigned Col, unsigned Offset)
: FileID(FileID), Line(Line), Col(Col), Offset(Offset) {}
};
-/// \brief A base class that handles reading serialized diagnostics from a file.
+/// A base class that handles reading serialized diagnostics from a file.
///
/// Subclasses should override the visit* methods with their logic for handling
/// the various constructs that are found in serialized diagnostics.
class SerializedDiagnosticReader {
public:
- SerializedDiagnosticReader() {}
- virtual ~SerializedDiagnosticReader() {}
+ SerializedDiagnosticReader() = default;
+ virtual ~SerializedDiagnosticReader() = default;
- /// \brief Read the diagnostics in \c File
+ /// Read the diagnostics in \c File
std::error_code readDiagnostics(StringRef File);
private:
enum class Cursor;
- /// \brief Read to the next record or block to process.
+ /// Read to the next record or block to process.
llvm::ErrorOr<Cursor> skipUntilRecordOrBlock(llvm::BitstreamCursor &Stream,
unsigned &BlockOrRecordId);
- /// \brief Read a metadata block from \c Stream.
+ /// Read a metadata block from \c Stream.
std::error_code readMetaBlock(llvm::BitstreamCursor &Stream);
- /// \brief Read a diagnostic block from \c Stream.
+ /// Read a diagnostic block from \c Stream.
std::error_code readDiagnosticBlock(llvm::BitstreamCursor &Stream);
protected:
- /// \brief Visit the start of a diagnostic block.
- virtual std::error_code visitStartOfDiagnostic() {
- return std::error_code();
- }
- /// \brief Visit the end of a diagnostic block.
- virtual std::error_code visitEndOfDiagnostic() { return std::error_code(); }
- /// \brief Visit a category. This associates the category \c ID to a \c Name.
+ /// Visit the start of a diagnostic block.
+ virtual std::error_code visitStartOfDiagnostic() { return {}; }
+
+ /// Visit the end of a diagnostic block.
+ virtual std::error_code visitEndOfDiagnostic() { return {}; }
+
+ /// Visit a category. This associates the category \c ID to a \c Name.
virtual std::error_code visitCategoryRecord(unsigned ID, StringRef Name) {
- return std::error_code();
+ return {};
}
- /// \brief Visit a flag. This associates the flag's \c ID to a \c Name.
+
+ /// Visit a flag. This associates the flag's \c ID to a \c Name.
virtual std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) {
- return std::error_code();
+ return {};
}
- /// \brief Visit a diagnostic.
+
+ /// Visit a diagnostic.
virtual std::error_code
visitDiagnosticRecord(unsigned Severity, const Location &Location,
unsigned Category, unsigned Flag, StringRef Message) {
- return std::error_code();
+ return {};
}
- /// \brief Visit a filename. This associates the file's \c ID to a \c Name.
+
+ /// Visit a filename. This associates the file's \c ID to a \c Name.
virtual std::error_code visitFilenameRecord(unsigned ID, unsigned Size,
unsigned Timestamp,
StringRef Name) {
- return std::error_code();
+ return {};
}
- /// \brief Visit a fixit hint.
+
+ /// Visit a fixit hint.
virtual std::error_code
visitFixitRecord(const Location &Start, const Location &End, StringRef Text) {
- return std::error_code();
+ return {};
}
- /// \brief Visit a source range.
+
+ /// Visit a source range.
virtual std::error_code visitSourceRangeRecord(const Location &Start,
const Location &End) {
- return std::error_code();
- }
- /// \brief Visit the version of the set of diagnostics.
- virtual std::error_code visitVersionRecord(unsigned Version) {
- return std::error_code();
+ return {};
}
+
+ /// Visit the version of the set of diagnostics.
+ virtual std::error_code visitVersionRecord(unsigned Version) { return {}; }
};
-} // end serialized_diags namespace
-} // end clang namespace
+} // namespace serialized_diags
+} // namespace clang
namespace std {
+
template <>
struct is_error_code_enum<clang::serialized_diags::SDError> : std::true_type {};
-}
-#endif
+} // namespace std
+
+#endif // LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICREADER_H
diff --git a/include/clang/Frontend/SerializedDiagnostics.h b/include/clang/Frontend/SerializedDiagnostics.h
index 2032cd3988dbf..dacbc678b7006 100644
--- a/include/clang/Frontend/SerializedDiagnostics.h
+++ b/include/clang/Frontend/SerializedDiagnostics.h
@@ -16,11 +16,11 @@ namespace clang {
namespace serialized_diags {
enum BlockIDs {
- /// \brief A top-level block which represents any meta data associated
+ /// A top-level block which represents any meta data associated
/// with the diagostics, including versioning of the format.
BLOCK_META = llvm::bitc::FIRST_APPLICATION_BLOCKID,
- /// \brief The this block acts as a container for all the information
+ /// The this block acts as a container for all the information
/// for a specific diagnostic.
BLOCK_DIAG
};
@@ -37,7 +37,7 @@ enum RecordIDs {
RECORD_LAST = RECORD_FIXIT
};
-/// \brief A stable version of DiagnosticIDs::Level.
+/// A stable version of DiagnosticIDs::Level.
///
/// Do not change the order of values in this enum, and please increment the
/// serialized diagnostics version number when you add to it.
@@ -50,7 +50,7 @@ enum Level {
Remark
};
-/// \brief The serialized diagnostics version number.
+/// The serialized diagnostics version number.
enum { VersionNumber = 2 };
} // end serialized_diags namespace
diff --git a/include/clang/Frontend/TextDiagnostic.h b/include/clang/Frontend/TextDiagnostic.h
index 1bbfe9fa02e32..9f33b866a1ebe 100644
--- a/include/clang/Frontend/TextDiagnostic.h
+++ b/include/clang/Frontend/TextDiagnostic.h
@@ -20,7 +20,7 @@
namespace clang {
-/// \brief Class to encapsulate the logic for formatting and printing a textual
+/// Class to encapsulate the logic for formatting and printing a textual
/// diagnostic message.
///
/// This class provides an interface for building and emitting a textual
@@ -42,7 +42,7 @@ public:
~TextDiagnostic() override;
- /// \brief Print the diagonstic level to a raw_ostream.
+ /// Print the diagonstic level to a raw_ostream.
///
/// This is a static helper that handles colorizing the level and formatting
/// it into an arbitrary output stream. This is used internally by the
@@ -54,7 +54,7 @@ public:
bool ShowColors,
bool CLFallbackMode = false);
- /// \brief Pretty-print a diagnostic message to a raw_ostream.
+ /// Pretty-print a diagnostic message to a raw_ostream.
///
/// This is a static helper to handle the line wrapping, colorizing, and
/// rendering of a diagnostic message to a particular ostream. It is
diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h
index 23f168e2232df..2295f9dbf3bfb 100644
--- a/include/clang/Frontend/TextDiagnosticBuffer.h
+++ b/include/clang/Frontend/TextDiagnosticBuffer.h
@@ -1,4 +1,4 @@
-//===--- TextDiagnosticBuffer.h - Buffer Text Diagnostics -------*- C++ -*-===//
+//===- TextDiagnosticBuffer.h - Buffer Text Diagnostics ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,37 +15,41 @@
#define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICBUFFER_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include <cstddef>
+#include <string>
+#include <utility>
#include <vector>
namespace clang {
-class Preprocessor;
-class SourceManager;
-
class TextDiagnosticBuffer : public DiagnosticConsumer {
public:
- typedef std::vector<std::pair<SourceLocation, std::string> > DiagList;
- typedef DiagList::iterator iterator;
- typedef DiagList::const_iterator const_iterator;
+ using DiagList = std::vector<std::pair<SourceLocation, std::string>>;
+ using iterator = DiagList::iterator;
+ using const_iterator = DiagList::const_iterator;
+
private:
DiagList Errors, Warnings, Remarks, Notes;
+
/// All - All diagnostics in the order in which they were generated. That
/// order likely doesn't correspond to user input order, but it at least
/// keeps notes in the right places. Each pair in the vector is a diagnostic
/// level and an index into the corresponding DiagList above.
std::vector<std::pair<DiagnosticsEngine::Level, size_t>> All;
+
public:
- const_iterator err_begin() const { return Errors.begin(); }
- const_iterator err_end() const { return Errors.end(); }
+ const_iterator err_begin() const { return Errors.begin(); }
+ const_iterator err_end() const { return Errors.end(); }
const_iterator warn_begin() const { return Warnings.begin(); }
- const_iterator warn_end() const { return Warnings.end(); }
+ const_iterator warn_end() const { return Warnings.end(); }
const_iterator remark_begin() const { return Remarks.begin(); }
- const_iterator remark_end() const { return Remarks.end(); }
+ const_iterator remark_end() const { return Remarks.end(); }
const_iterator note_begin() const { return Notes.begin(); }
- const_iterator note_end() const { return Notes.end(); }
+ const_iterator note_end() const { return Notes.end(); }
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const Diagnostic &Info) override;
@@ -55,6 +59,6 @@ public:
void FlushDiagnostics(DiagnosticsEngine &Diags) const;
};
-} // end namspace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICBUFFER_H
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index 07cee9f8ad8aa..3cb4e02edf0d0 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -29,7 +29,7 @@ class TextDiagnosticPrinter : public DiagnosticConsumer {
raw_ostream &OS;
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
- /// \brief Handle to the currently active text diagnostic emitter.
+ /// Handle to the currently active text diagnostic emitter.
std::unique_ptr<TextDiagnostic> TextDiag;
/// A string to prefix to error messages.
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index 8ccc31982dabd..67912a8dfcdde 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -1,4 +1,4 @@
-//===--- Utils.h - Misc utilities for the front-end -------------*- C++ -*-===//
+//===- Utils.h - Misc utilities for the front-end ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,45 +15,49 @@
#define LLVM_CLANG_FRONTEND_UTILS_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/VirtualFileSystem.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Option/OptSpecifier.h"
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <system_error>
#include <utility>
+#include <vector>
namespace llvm {
-class raw_fd_ostream;
+
class Triple;
namespace opt {
+
class ArgList;
-}
-}
+
+} // namespace opt
+
+} // namespace llvm
namespace clang {
-class ASTConsumer;
+
class ASTReader;
class CompilerInstance;
class CompilerInvocation;
-class Decl;
class DependencyOutputOptions;
class DiagnosticsEngine;
-class DiagnosticOptions;
class ExternalSemaSource;
-class FileManager;
+class FrontendOptions;
class HeaderSearch;
class HeaderSearchOptions;
-class IdentifierTable;
class LangOptions;
class PCHContainerReader;
class Preprocessor;
class PreprocessorOptions;
class PreprocessorOutputOptions;
-class SourceManager;
-class Stmt;
-class TargetInfo;
-class FrontendOptions;
/// Apply the header search options to get given HeaderSearch object.
void ApplyHeaderSearchOptions(HeaderSearch &HS,
@@ -68,7 +72,7 @@ void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts,
const FrontendOptions &FEOpts);
/// DoPrintPreprocessedInput - Implement -E mode.
-void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
+void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
const PreprocessorOutputOptions &Opts);
/// An interface for collecting the dependencies of a compilation. Users should
@@ -78,9 +82,11 @@ void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
/// interface.
class DependencyCollector {
public:
+ virtual ~DependencyCollector();
+
virtual void attachToPreprocessor(Preprocessor &PP);
virtual void attachToASTReader(ASTReader &R);
- llvm::ArrayRef<std::string> getDependencies() const { return Dependencies; }
+ ArrayRef<std::string> getDependencies() const { return Dependencies; }
/// Called when a new file is seen. Return true if \p Filename should be added
/// to the list of dependencies.
@@ -88,17 +94,19 @@ public:
/// The default implementation ignores <built-in> and system files.
virtual bool sawDependency(StringRef Filename, bool FromModule,
bool IsSystem, bool IsModuleFile, bool IsMissing);
+
/// Called when the end of the main file is reached.
- virtual void finishedMainFile() { }
+ virtual void finishedMainFile() {}
+
/// Return true if system files should be passed to sawDependency().
virtual bool needSystemDependencies() { return false; }
- virtual ~DependencyCollector();
-public: // implementation detail
+ // implementation detail
/// Add a dependency \p Filename if it has not been seen before and
/// sawDependency() returns true.
void maybeAddDependency(StringRef Filename, bool FromModule, bool IsSystem,
bool IsModuleFile, bool IsMissing);
+
private:
llvm::StringSet<> Seen;
std::vector<std::string> Dependencies;
@@ -110,10 +118,13 @@ private:
/// loaded.
class DependencyFileGenerator {
void *Impl; // Opaque implementation
+
DependencyFileGenerator(void *Impl);
+
public:
static DependencyFileGenerator *CreateAndAttachToPreprocessor(
Preprocessor &PP, const DependencyOutputOptions &Opts);
+
void AttachToASTReader(ASTReader &R);
};
@@ -124,15 +135,20 @@ class ModuleDependencyCollector : public DependencyCollector {
bool HasErrors = false;
llvm::StringSet<> Seen;
vfs::YAMLVFSWriter VFSWriter;
-
llvm::StringMap<std::string> SymLinkMap;
bool getRealPath(StringRef SrcPath, SmallVectorImpl<char> &Result);
- std::error_code copyToRoot(StringRef Src, StringRef Dst = "");
+ std::error_code copyToRoot(StringRef Src, StringRef Dst = {});
+
public:
+ ModuleDependencyCollector(std::string DestDir)
+ : DestDir(std::move(DestDir)) {}
+ ~ModuleDependencyCollector() override { writeFileMap(); }
+
StringRef getDest() { return DestDir; }
bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; }
- void addFile(StringRef Filename, StringRef FileDst = "");
+ void addFile(StringRef Filename, StringRef FileDst = {});
+
void addFileMapping(StringRef VPath, StringRef RPath) {
VFSWriter.addFileMapping(VPath, RPath);
}
@@ -142,9 +158,6 @@ public:
void writeFileMap();
bool hasErrors() { return HasErrors; }
- ModuleDependencyCollector(std::string DestDir)
- : DestDir(std::move(DestDir)) {}
- ~ModuleDependencyCollector() { writeFileMap(); }
};
/// AttachDependencyGraphGen - Create a dependency graph generator, and attach
@@ -167,7 +180,7 @@ void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile,
void AttachHeaderIncludeGen(Preprocessor &PP,
const DependencyOutputOptions &DepOpts,
bool ShowAllHeaders = false,
- StringRef OutputPath = "",
+ StringRef OutputPath = {},
bool ShowDepth = true, bool MSStyle = false);
/// Cache tokens for use with PCH. Note that this requires a seekable stream.
@@ -221,6 +234,12 @@ template <typename T> void BuryPointer(std::unique_ptr<T> Ptr) {
BuryPointer(Ptr.release());
}
-} // end namespace clang
+// Frontend timing utils
+
+/// If the user specifies the -ftime-report argument on an Clang command line
+/// then the value of this boolean will be true, otherwise false.
+extern bool FrontendTimesIsEnabled;
+
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_FRONTEND_UTILS_H
diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h
index 8d71fb98b0bb1..9d985bc4955f8 100644
--- a/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -11,18 +11,24 @@
#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/STLExtras.h"
-#include <climits>
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <limits>
#include <memory>
+#include <string>
+#include <vector>
namespace clang {
-class DiagnosticsEngine;
-class TextDiagnosticBuffer;
class FileEntry;
+class LangOptions;
+class SourceManager;
+class TextDiagnosticBuffer;
/// VerifyDiagnosticConsumer - Create a diagnostic client which will use
/// markers in the input source to check that all the emitted diagnostics match
@@ -153,7 +159,7 @@ public:
public:
/// Constant representing n or more matches.
- static const unsigned MaxCount = UINT_MAX;
+ static const unsigned MaxCount = std::numeric_limits<unsigned>::max();
SourceLocation DirectiveLoc;
SourceLocation DiagnosticLoc;
@@ -161,7 +167,9 @@ public:
unsigned Min, Max;
bool MatchAnyLine;
- virtual ~Directive() { }
+ Directive(const Directive &) = delete;
+ Directive &operator=(const Directive &) = delete;
+ virtual ~Directive() = default;
// Returns true if directive text is valid.
// Otherwise returns false and populates E.
@@ -173,22 +181,17 @@ public:
protected:
Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max)
- : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
- Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
- assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
- assert((!DiagnosticLoc.isInvalid() || MatchAnyLine) &&
- "DiagnosticLoc is invalid!");
+ : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
+ Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
+ assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
+ assert((!DiagnosticLoc.isInvalid() || MatchAnyLine) &&
+ "DiagnosticLoc is invalid!");
}
-
- private:
- Directive(const Directive &) = delete;
- void operator=(const Directive &) = delete;
};
- typedef std::vector<std::unique_ptr<Directive>> DirectiveList;
+ using DirectiveList = std::vector<std::unique_ptr<Directive>>;
/// ExpectedData - owns directive objects and deletes on destructor.
- ///
struct ExpectedData {
DirectiveList Errors;
DirectiveList Warnings;
@@ -215,14 +218,15 @@ private:
DiagnosticConsumer *PrimaryClient;
std::unique_ptr<DiagnosticConsumer> PrimaryClientOwner;
std::unique_ptr<TextDiagnosticBuffer> Buffer;
- const Preprocessor *CurrentPreprocessor;
- const LangOptions *LangOpts;
- SourceManager *SrcManager;
- unsigned ActiveSourceFiles;
+ const Preprocessor *CurrentPreprocessor = nullptr;
+ const LangOptions *LangOpts = nullptr;
+ SourceManager *SrcManager = nullptr;
+ unsigned ActiveSourceFiles = 0;
DirectiveStatus Status;
ExpectedData ED;
void CheckDiagnostics();
+
void setSourceManager(SourceManager &SM) {
assert((!SrcManager || SrcManager == &SM) && "SourceManager changed!");
SrcManager = &SM;
@@ -231,14 +235,18 @@ private:
// These facilities are used for validation in debug builds.
class UnparsedFileStatus {
llvm::PointerIntPair<const FileEntry *, 1, bool> Data;
+
public:
UnparsedFileStatus(const FileEntry *File, bool FoundDirectives)
- : Data(File, FoundDirectives) {}
+ : Data(File, FoundDirectives) {}
+
const FileEntry *getFile() const { return Data.getPointer(); }
bool foundDirectives() const { return Data.getInt(); }
};
- typedef llvm::DenseMap<FileID, const FileEntry *> ParsedFilesMap;
- typedef llvm::DenseMap<FileID, UnparsedFileStatus> UnparsedFilesMap;
+
+ using ParsedFilesMap = llvm::DenseMap<FileID, const FileEntry *>;
+ using UnparsedFilesMap = llvm::DenseMap<FileID, UnparsedFileStatus>;
+
ParsedFilesMap ParsedFiles;
UnparsedFilesMap UnparsedFiles;
@@ -265,7 +273,7 @@ public:
IsUnparsedNoDirectives
};
- /// \brief Update lists of parsed and unparsed files.
+ /// Update lists of parsed and unparsed files.
void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS);
bool HandleComment(Preprocessor &PP, SourceRange Comment) override;
@@ -274,6 +282,6 @@ public:
const Diagnostic &Info) override;
};
-} // end namspace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H
diff --git a/include/clang/FrontendTool/Utils.h b/include/clang/FrontendTool/Utils.h
index 031ee7df70aed..2e6b7b5076bb6 100644
--- a/include/clang/FrontendTool/Utils.h
+++ b/include/clang/FrontendTool/Utils.h
@@ -15,9 +15,18 @@
#ifndef LLVM_CLANG_FRONTENDTOOL_UTILS_H
#define LLVM_CLANG_FRONTENDTOOL_UTILS_H
+#include <memory>
+
namespace clang {
class CompilerInstance;
+class FrontendAction;
+
+/// Construct the FrontendAction of a compiler invocation based on the
+/// options specified for the compiler invocation.
+///
+/// \return - The created FrontendAction object
+std::unique_ptr<FrontendAction> CreateFrontendAction(CompilerInstance &CI);
/// ExecuteCompilerInvocation - Execute the given actions described by the
/// compiler invocation object in the given compiler instance.
diff --git a/include/clang/Index/IndexDataConsumer.h b/include/clang/Index/IndexDataConsumer.h
index 080f4cb4d0978..6e11455661a09 100644
--- a/include/clang/Index/IndexDataConsumer.h
+++ b/include/clang/Index/IndexDataConsumer.h
@@ -1,4 +1,4 @@
-//===--- IndexDataConsumer.h - Abstract index data consumer ---------------===//
+//===--- IndexDataConsumer.h - Abstract index data consumer -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -42,23 +42,18 @@ public:
/// \returns true to continue indexing, or false to abort.
virtual bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles,
ArrayRef<SymbolRelation> Relations,
- FileID FID, unsigned Offset,
- ASTNodeInfo ASTNode);
+ SourceLocation Loc, ASTNodeInfo ASTNode);
/// \returns true to continue indexing, or false to abort.
virtual bool handleMacroOccurence(const IdentifierInfo *Name,
const MacroInfo *MI, SymbolRoleSet Roles,
- FileID FID, unsigned Offset);
+ SourceLocation Loc);
/// \returns true to continue indexing, or false to abort.
virtual bool handleModuleOccurence(const ImportDecl *ImportD,
- SymbolRoleSet Roles,
- FileID FID, unsigned Offset);
+ SymbolRoleSet Roles, SourceLocation Loc);
virtual void finish() {}
-
-private:
- virtual void _anchor();
};
} // namespace index
diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h
index 08f2839f37e85..068796141df8b 100644
--- a/include/clang/Index/IndexSymbol.h
+++ b/include/clang/Index/IndexSymbol.h
@@ -1,4 +1,4 @@
-//===--- IndexSymbol.h - Types and functions for indexing symbols ---------===//
+//===- IndexSymbol.h - Types and functions for indexing symbols -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,6 +11,7 @@
#define LLVM_CLANG_INDEX_INDEXSYMBOL_H
#include "clang/Basic/LLVM.h"
+#include "clang/Lex/MacroInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/DataTypes.h"
@@ -89,30 +90,35 @@ enum class SymbolProperty : SymbolPropertySet {
static const unsigned SymbolPropertyBitNum = 8;
/// Set of roles that are attributed to symbol occurrences.
+///
+/// Low 9 bits of clang-c/include/Index.h CXSymbolRole mirrors this enum.
enum class SymbolRole : uint32_t {
Declaration = 1 << 0,
- Definition = 1 << 1,
- Reference = 1 << 2,
- Read = 1 << 3,
- Write = 1 << 4,
- Call = 1 << 5,
- Dynamic = 1 << 6,
- AddressOf = 1 << 7,
- Implicit = 1 << 8,
+ Definition = 1 << 1,
+ Reference = 1 << 2,
+ Read = 1 << 3,
+ Write = 1 << 4,
+ Call = 1 << 5,
+ Dynamic = 1 << 6,
+ AddressOf = 1 << 7,
+ Implicit = 1 << 8,
+ // FIXME: this is not mirrored in CXSymbolRole.
+ // Note that macro occurrences aren't currently supported in libclang.
+ Undefinition = 1 << 9, // macro #undef
// Relation roles.
- RelationChildOf = 1 << 9,
- RelationBaseOf = 1 << 10,
- RelationOverrideOf = 1 << 11,
- RelationReceivedBy = 1 << 12,
- RelationCalledBy = 1 << 13,
- RelationExtendedBy = 1 << 14,
- RelationAccessorOf = 1 << 15,
- RelationContainedBy = 1 << 16,
- RelationIBTypeOf = 1 << 17,
- RelationSpecializationOf = 1 << 18,
+ RelationChildOf = 1 << 10,
+ RelationBaseOf = 1 << 11,
+ RelationOverrideOf = 1 << 12,
+ RelationReceivedBy = 1 << 13,
+ RelationCalledBy = 1 << 14,
+ RelationExtendedBy = 1 << 15,
+ RelationAccessorOf = 1 << 16,
+ RelationContainedBy = 1 << 17,
+ RelationIBTypeOf = 1 << 18,
+ RelationSpecializationOf = 1 << 19,
};
-static const unsigned SymbolRoleBitNum = 19;
+static const unsigned SymbolRoleBitNum = 20;
typedef unsigned SymbolRoleSet;
/// Represents a relation to another symbol for a symbol occurrence.
@@ -133,6 +139,8 @@ struct SymbolInfo {
SymbolInfo getSymbolInfo(const Decl *D);
+SymbolInfo getSymbolInfoForMacro(const MacroInfo &MI);
+
bool isFunctionLocalSymbol(const Decl *D);
void applyForEachSymbolRole(SymbolRoleSet Roles,
diff --git a/include/clang/Index/IndexingAction.h b/include/clang/Index/IndexingAction.h
index fb703be4e5f53..0d09c403483d9 100644
--- a/include/clang/Index/IndexingAction.h
+++ b/include/clang/Index/IndexingAction.h
@@ -1,4 +1,4 @@
-//===--- IndexingAction.h - Frontend index action -------------------------===//
+//===--- IndexingAction.h - Frontend index action ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,6 +11,7 @@
#define LLVM_CLANG_INDEX_INDEXINGACTION_H
#include "clang/Basic/LLVM.h"
+#include "clang/Lex/PPCallbacks.h"
#include "llvm/ADT/ArrayRef.h"
#include <memory>
@@ -38,25 +39,35 @@ struct IndexingOptions {
SystemSymbolFilterKind SystemSymbolFilter
= SystemSymbolFilterKind::DeclarationsOnly;
bool IndexFunctionLocals = false;
+ bool IndexImplicitInstantiation = false;
};
+/// Creates a frontend action that indexes all symbols (macros and AST decls).
/// \param WrappedAction another frontend action to wrap over or null.
std::unique_ptr<FrontendAction>
createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
IndexingOptions Opts,
std::unique_ptr<FrontendAction> WrappedAction);
-void indexASTUnit(ASTUnit &Unit,
- std::shared_ptr<IndexDataConsumer> DataConsumer,
+/// Recursively indexes all decls in the AST.
+/// Note that this does not index macros.
+void indexASTUnit(ASTUnit &Unit, IndexDataConsumer &DataConsumer,
IndexingOptions Opts);
+/// Recursively indexes \p Decls.
+/// Note that this does not index macros.
void indexTopLevelDecls(ASTContext &Ctx, ArrayRef<const Decl *> Decls,
- std::shared_ptr<IndexDataConsumer> DataConsumer,
- IndexingOptions Opts);
+ IndexDataConsumer &DataConsumer, IndexingOptions Opts);
+/// Creates a PPCallbacks that indexes macros and feeds macros to \p Consumer.
+/// The caller is responsible for calling `Consumer.setPreprocessor()`.
+std::unique_ptr<PPCallbacks> indexMacrosCallback(IndexDataConsumer &Consumer,
+ IndexingOptions Opts);
+
+/// Recursively indexes all top-level decls in the module.
+/// FIXME: make this index macros as well.
void indexModuleFile(serialization::ModuleFile &Mod, ASTReader &Reader,
- std::shared_ptr<IndexDataConsumer> DataConsumer,
- IndexingOptions Opts);
+ IndexDataConsumer &DataConsumer, IndexingOptions Opts);
} // namespace index
} // namespace clang
diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h
index 8c661bd63cd8a..1ece321746a60 100644
--- a/include/clang/Index/USRGeneration.h
+++ b/include/clang/Index/USRGeneration.h
@@ -1,4 +1,4 @@
-//===- USRGeneration.h - Routines for USR generation ----------------------===//
+//===- USRGeneration.h - Routines for USR generation ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -25,33 +25,33 @@ static inline StringRef getUSRSpacePrefix() {
return "c:";
}
-/// \brief Generate a USR for a Decl, including the USR prefix.
+/// Generate a USR for a Decl, including the USR prefix.
/// \returns true if the results should be ignored, false otherwise.
bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf);
-/// \brief Generate a USR fragment for an Objective-C class.
+/// Generate a USR fragment for an Objective-C class.
void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
StringRef ExtSymbolDefinedIn = "",
StringRef CategoryContextExtSymbolDefinedIn = "");
-/// \brief Generate a USR fragment for an Objective-C class category.
+/// Generate a USR fragment for an Objective-C class category.
void generateUSRForObjCCategory(StringRef Cls, StringRef Cat, raw_ostream &OS,
StringRef ClsExtSymbolDefinedIn = "",
StringRef CatExtSymbolDefinedIn = "");
-/// \brief Generate a USR fragment for an Objective-C instance variable. The
+/// Generate a USR fragment for an Objective-C instance variable. The
/// complete USR can be created by concatenating the USR for the
/// encompassing class with this USR fragment.
void generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS);
-/// \brief Generate a USR fragment for an Objective-C method.
+/// Generate a USR fragment for an Objective-C method.
void generateUSRForObjCMethod(StringRef Sel, bool IsInstanceMethod,
raw_ostream &OS);
-/// \brief Generate a USR fragment for an Objective-C property.
+/// Generate a USR fragment for an Objective-C property.
void generateUSRForObjCProperty(StringRef Prop, bool isClassProp, raw_ostream &OS);
-/// \brief Generate a USR fragment for an Objective-C protocol.
+/// Generate a USR fragment for an Objective-C protocol.
void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS,
StringRef ExtSymbolDefinedIn = "");
@@ -62,7 +62,7 @@ void generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS,
/// Generate a USR fragment for an enum constant.
void generateUSRForEnumConstant(StringRef EnumConstantName, raw_ostream &OS);
-/// \brief Generate a USR for a macro, including the USR prefix.
+/// Generate a USR for a macro, including the USR prefix.
///
/// \returns true on error, false on success.
bool generateUSRForMacro(const MacroDefinitionRecord *MD,
diff --git a/include/clang/Lex/CodeCompletionHandler.h b/include/clang/Lex/CodeCompletionHandler.h
index 91c3b7811f079..be153cc1ad508 100644
--- a/include/clang/Lex/CodeCompletionHandler.h
+++ b/include/clang/Lex/CodeCompletionHandler.h
@@ -19,13 +19,13 @@ namespace clang {
class IdentifierInfo;
class MacroInfo;
-/// \brief Callback handler that receives notifications when performing code
+/// Callback handler that receives notifications when performing code
/// completion within the preprocessor.
class CodeCompletionHandler {
public:
virtual ~CodeCompletionHandler();
- /// \brief Callback invoked when performing code completion for a preprocessor
+ /// Callback invoked when performing code completion for a preprocessor
/// directive.
///
/// This callback will be invoked when the preprocessor processes a '#' at the
@@ -35,22 +35,22 @@ public:
/// already.
virtual void CodeCompleteDirective(bool InConditional) { }
- /// \brief Callback invoked when performing code completion within a block of
+ /// Callback invoked when performing code completion within a block of
/// code that was excluded due to preprocessor conditionals.
virtual void CodeCompleteInConditionalExclusion() { }
- /// \brief Callback invoked when performing code completion in a context
+ /// Callback invoked when performing code completion in a context
/// where the name of a macro is expected.
///
/// \param IsDefinition Whether this is the definition of a macro, e.g.,
/// in a \#define.
virtual void CodeCompleteMacroName(bool IsDefinition) { }
- /// \brief Callback invoked when performing code completion in a preprocessor
+ /// Callback invoked when performing code completion in a preprocessor
/// expression, such as the condition of an \#if or \#elif directive.
virtual void CodeCompletePreprocessorExpression() { }
- /// \brief Callback invoked when performing code completion inside a
+ /// Callback invoked when performing code completion inside a
/// function-like macro argument.
///
/// There will be another callback invocation after the macro arguments are
@@ -60,7 +60,7 @@ public:
MacroInfo *MacroInfo,
unsigned ArgumentIndex) { }
- /// \brief Callback invoked when performing code completion in a part of the
+ /// Callback invoked when performing code completion in a part of the
/// file where we expect natural language, e.g., a comment, string, or
/// \#error directive.
virtual void CodeCompleteNaturalLanguage() { }
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
index dcd58f434fa24..222ebf025ac04 100644
--- a/include/clang/Lex/DirectoryLookup.h
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -55,10 +55,10 @@ private:
/// normal directory, a framework, or a headermap.
unsigned LookupType : 2;
- /// \brief Whether this is a header map used when building a framework.
+ /// Whether this is a header map used when building a framework.
unsigned IsIndexHeaderMap : 1;
- /// \brief Whether we've performed an exhaustive search for module maps
+ /// Whether we've performed an exhaustive search for module maps
/// within the subdirectories of this directory.
unsigned SearchedAllModuleMaps : 1;
@@ -118,11 +118,11 @@ public:
/// isHeaderMap - Return true if this is a header map, not a normal directory.
bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; }
- /// \brief Determine whether we have already searched this entire
+ /// Determine whether we have already searched this entire
/// directory for module maps.
bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; }
- /// \brief Specify whether we have already searched all of the subdirectories
+ /// Specify whether we have already searched all of the subdirectories
/// for module maps.
void setSearchedAllModuleMaps(bool SAMM) {
SearchedAllModuleMaps = SAMM;
@@ -134,12 +134,12 @@ public:
return (SrcMgr::CharacteristicKind)DirCharacteristic;
}
- /// \brief Whether this describes a system header directory.
+ /// Whether this describes a system header directory.
bool isSystemHeaderDirectory() const {
return getDirCharacteristic() != SrcMgr::C_User;
}
- /// \brief Whether this header map is building a framework or not.
+ /// Whether this header map is building a framework or not.
bool isIndexHeaderMap() const {
return isHeaderMap() && IsIndexHeaderMap;
}
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
index adf8e713e99e6..f34be682617cd 100644
--- a/include/clang/Lex/ExternalPreprocessorSource.h
+++ b/include/clang/Lex/ExternalPreprocessorSource.h
@@ -19,7 +19,7 @@ namespace clang {
class IdentifierInfo;
class Module;
-/// \brief Abstract interface for external sources of preprocessor
+/// Abstract interface for external sources of preprocessor
/// information.
///
/// This abstract class allows an external sources (such as the \c ASTReader)
@@ -28,18 +28,18 @@ class ExternalPreprocessorSource {
public:
virtual ~ExternalPreprocessorSource();
- /// \brief Read the set of macros defined by this external macro source.
+ /// Read the set of macros defined by this external macro source.
virtual void ReadDefinedMacros() = 0;
- /// \brief Update an out-of-date identifier.
+ /// Update an out-of-date identifier.
virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0;
- /// \brief Return the identifier associated with the given ID number.
+ /// Return the identifier associated with the given ID number.
///
/// The ID 0 is associated with the NULL identifier.
virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0;
- /// \brief Map a module ID to a module.
+ /// Map a module ID to a module.
virtual Module *getModule(unsigned ModuleID) = 0;
};
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 6b9dbfcd1e934..b7147c54faacd 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -46,13 +46,13 @@ class Module;
class Preprocessor;
class TargetInfo;
-/// \brief The preprocessor keeps track of this information for each
+/// The preprocessor keeps track of this information for each
/// file that is \#included.
struct HeaderFileInfo {
- /// \brief True if this is a \#import'd or \#pragma once file.
+ /// True if this is a \#import'd or \#pragma once file.
unsigned isImport : 1;
- /// \brief True if this is a \#pragma once file.
+ /// True if this is a \#pragma once file.
unsigned isPragmaOnce : 1;
/// DirInfo - Keep track of whether this is a system header, and if so,
@@ -61,21 +61,21 @@ struct HeaderFileInfo {
/// SrcMgr::CharacteristicKind.
unsigned DirInfo : 3;
- /// \brief Whether this header file info was supplied by an external source,
+ /// Whether this header file info was supplied by an external source,
/// and has not changed since.
unsigned External : 1;
- /// \brief Whether this header is part of a module.
+ /// Whether this header is part of a module.
unsigned isModuleHeader : 1;
- /// \brief Whether this header is part of the module that we are building.
+ /// Whether this header is part of the module that we are building.
unsigned isCompilingModuleHeader : 1;
- /// \brief Whether this structure is considered to already have been
+ /// Whether this structure is considered to already have been
/// "resolved", meaning that it was loaded from the external source.
unsigned Resolved : 1;
- /// \brief Whether this is a header inside a framework that is currently
+ /// Whether this is a header inside a framework that is currently
/// being built.
///
/// When a framework is being built, the headers have not yet been placed
@@ -84,13 +84,13 @@ struct HeaderFileInfo {
/// those framework headers.
unsigned IndexHeaderMapHeader : 1;
- /// \brief Whether this file has been looked up as a header.
+ /// Whether this file has been looked up as a header.
unsigned IsValid : 1;
- /// \brief The number of times the file has been included already.
+ /// The number of times the file has been included already.
unsigned short NumIncludes = 0;
- /// \brief The ID number of the controlling macro.
+ /// The ID number of the controlling macro.
///
/// This ID number will be non-zero when there is a controlling
/// macro whose IdentifierInfo may not yet have been loaded from
@@ -107,7 +107,7 @@ struct HeaderFileInfo {
/// external storage.
const IdentifierInfo *ControllingMacro = nullptr;
- /// \brief If this header came from a framework include, this is the name
+ /// If this header came from a framework include, this is the name
/// of the framework.
StringRef Framework;
@@ -116,12 +116,12 @@ struct HeaderFileInfo {
External(false), isModuleHeader(false), isCompilingModuleHeader(false),
Resolved(false), IndexHeaderMapHeader(false), IsValid(false) {}
- /// \brief Retrieve the controlling macro for this header file, if
+ /// Retrieve the controlling macro for this header file, if
/// any.
const IdentifierInfo *
getControllingMacro(ExternalPreprocessorSource *External);
- /// \brief Determine whether this is a non-default header file info, e.g.,
+ /// Determine whether this is a non-default header file info, e.g.,
/// it corresponds to an actual header we've included or tried to include.
bool isNonDefault() const {
return isImport || isPragmaOnce || NumIncludes || ControllingMacro ||
@@ -129,13 +129,13 @@ struct HeaderFileInfo {
}
};
-/// \brief An external source of header file information, which may supply
+/// An external source of header file information, which may supply
/// information about header files already included.
class ExternalHeaderFileInfoSource {
public:
virtual ~ExternalHeaderFileInfoSource();
- /// \brief Retrieve the header file information for the given file entry.
+ /// Retrieve the header file information for the given file entry.
///
/// \returns Header file information for the given file entry, with the
/// \c External bit set. If the file entry is not known, return a
@@ -143,7 +143,7 @@ public:
virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
};
-/// \brief Encapsulates the information needed to find the file referenced
+/// Encapsulates the information needed to find the file referenced
/// by a \#include or \#include_next, (sub-)framework lookup, etc.
class HeaderSearch {
friend class DirectoryLookup;
@@ -159,7 +159,7 @@ class HeaderSearch {
bool IsUserSpecifiedSystemFramework;
};
- /// \brief Header-search options used to initialize this header search.
+ /// Header-search options used to initialize this header search.
std::shared_ptr<HeaderSearchOptions> HSOpts;
DiagnosticsEngine &Diags;
@@ -176,7 +176,7 @@ class HeaderSearch {
unsigned SystemDirIdx = 0;
bool NoCurDirSearch = false;
- /// \brief \#include prefixes for which the 'system header' property is
+ /// \#include prefixes for which the 'system header' property is
/// overridden.
///
/// For a \#include "x" or \#include \<x> directive, the last string in this
@@ -184,10 +184,10 @@ class HeaderSearch {
/// a system header.
std::vector<std::pair<std::string, bool>> SystemHeaderPrefixes;
- /// \brief The path to the module cache.
+ /// The path to the module cache.
std::string ModuleCachePath;
- /// \brief All of the preprocessor-specific data about files that are
+ /// All of the preprocessor-specific data about files that are
/// included, indexed by the FileEntry's UID.
mutable std::vector<HeaderFileInfo> FileInfo;
@@ -215,7 +215,7 @@ class HeaderSearch {
};
llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache;
- /// \brief Collection mapping a framework or subframework
+ /// Collection mapping a framework or subframework
/// name like "Carbon" to the Carbon.framework directory.
llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap;
@@ -230,26 +230,26 @@ class HeaderSearch {
/// headermaps. This vector owns the headermap.
std::vector<std::pair<const FileEntry *, const HeaderMap *>> HeaderMaps;
- /// \brief The mapping between modules and headers.
+ /// The mapping between modules and headers.
mutable ModuleMap ModMap;
- /// \brief Describes whether a given directory has a module map in it.
+ /// Describes whether a given directory has a module map in it.
llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
- /// \brief Set of module map files we've already loaded, and a flag indicating
+ /// Set of module map files we've already loaded, and a flag indicating
/// whether they were valid or not.
llvm::DenseMap<const FileEntry *, bool> LoadedModuleMaps;
- /// \brief Uniqued set of framework names, which is used to track which
+ /// Uniqued set of framework names, which is used to track which
/// headers were included as framework headers.
llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
- /// \brief Entity used to resolve the identifier IDs of controlling
+ /// Entity used to resolve the identifier IDs of controlling
/// macros into IdentifierInfo pointers, and keep the identifire up to date,
/// as needed.
ExternalPreprocessorSource *ExternalLookup = nullptr;
- /// \brief Entity used to look up stored header file information.
+ /// Entity used to look up stored header file information.
ExternalHeaderFileInfoSource *ExternalSource = nullptr;
// Various statistics we track for performance analysis.
@@ -266,18 +266,20 @@ public:
HeaderSearch &operator=(const HeaderSearch &) = delete;
~HeaderSearch();
- /// \brief Retrieve the header-search options with which this header search
+ /// Retrieve the header-search options with which this header search
/// was initialized.
HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; }
FileManager &getFileMgr() const { return FileMgr; }
- /// \brief Interface for setting the file search paths.
+ DiagnosticsEngine &getDiags() const { return Diags; }
+
+ /// Interface for setting the file search paths.
void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
unsigned angledDirIdx, unsigned systemDirIdx,
bool noCurDirSearch) {
assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
- "Directory indicies are unordered");
+ "Directory indices are unordered");
SearchDirs = dirs;
AngledDirIdx = angledDirIdx;
SystemDirIdx = systemDirIdx;
@@ -285,7 +287,7 @@ public:
//LookupFileCache.clear();
}
- /// \brief Add an additional search path.
+ /// Add an additional search path.
void AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
SearchDirs.insert(SearchDirs.begin() + idx, dir);
@@ -294,15 +296,15 @@ public:
SystemDirIdx++;
}
- /// \brief Set the list of system header prefixes.
+ /// Set the list of system header prefixes.
void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool>> P) {
SystemHeaderPrefixes.assign(P.begin(), P.end());
}
- /// \brief Checks whether the map exists or not.
+ /// Checks whether the map exists or not.
bool HasIncludeAliasMap() const { return (bool)IncludeAliases; }
- /// \brief Map the source include name to the dest include name.
+ /// Map the source include name to the dest include name.
///
/// The Source should include the angle brackets or quotes, the dest
/// should not. This allows for distinction between <> and "" headers.
@@ -326,20 +328,20 @@ public:
return {};
}
- /// \brief Set the path to the module cache.
+ /// Set the path to the module cache.
void setModuleCachePath(StringRef CachePath) {
ModuleCachePath = CachePath;
}
- /// \brief Retrieve the path to the module cache.
+ /// Retrieve the path to the module cache.
StringRef getModuleCachePath() const { return ModuleCachePath; }
- /// \brief Consider modules when including files from this directory.
+ /// Consider modules when including files from this directory.
void setDirectoryHasModuleMap(const DirectoryEntry* Dir) {
DirectoryHasModuleMap[Dir] = true;
}
- /// \brief Forget everything we know about headers so far.
+ /// Forget everything we know about headers so far.
void ClearFileInfo() {
FileInfo.clear();
}
@@ -352,16 +354,16 @@ public:
return ExternalLookup;
}
- /// \brief Set the external source of header information.
+ /// Set the external source of header information.
void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
ExternalSource = ES;
}
- /// \brief Set the target information for the header search, if not
+ /// Set the target information for the header search, if not
/// already known.
void setTarget(const TargetInfo &Target);
- /// \brief Given a "foo" or \<foo> reference, look up the indicated file,
+ /// Given a "foo" or \<foo> reference, look up the indicated file,
/// return null on failure.
///
/// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
@@ -399,7 +401,7 @@ public:
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
bool *IsMapped, bool SkipCache = false, bool BuildSystemModule = false);
- /// \brief Look up a subframework for the specified \#include file.
+ /// Look up a subframework for the specified \#include file.
///
/// For example, if \#include'ing <HIToolbox/HIToolbox.h> from
/// within ".../Carbon.framework/Headers/Carbon.h", check to see if
@@ -410,13 +412,13 @@ public:
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule);
- /// \brief Look up the specified framework name in our framework cache.
+ /// Look up the specified framework name in our framework cache.
/// \returns The DirectoryEntry it is in if we know, null otherwise.
FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) {
return FrameworkMap[FWName];
}
- /// \brief Mark the specified file as a target of of a \#include,
+ /// Mark the specified file as a target of a \#include,
/// \#include_next, or \#import directive.
///
/// \return false if \#including the file will have no effect or true
@@ -425,13 +427,13 @@ public:
bool isImport, bool ModulesEnabled,
Module *CorrespondingModule);
- /// \brief Return whether the specified file is a normal header,
+ /// Return whether the specified file is a normal header,
/// a system header, or a C++ friendly system header.
SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
}
- /// \brief Mark the specified file as a "once only" file, e.g. due to
+ /// Mark the specified file as a "once only" file, e.g. due to
/// \#pragma once.
void MarkFileIncludeOnce(const FileEntry *File) {
HeaderFileInfo &FI = getFileInfo(File);
@@ -439,24 +441,24 @@ public:
FI.isPragmaOnce = true;
}
- /// \brief Mark the specified file as a system header, e.g. due to
+ /// Mark the specified file as a system header, e.g. due to
/// \#pragma GCC system_header.
void MarkFileSystemHeader(const FileEntry *File) {
getFileInfo(File).DirInfo = SrcMgr::C_System;
}
- /// \brief Mark the specified file as part of a module.
+ /// Mark the specified file as part of a module.
void MarkFileModuleHeader(const FileEntry *File,
ModuleMap::ModuleHeaderRole Role,
bool IsCompiledModuleHeader);
- /// \brief Increment the count for the number of times the specified
+ /// Increment the count for the number of times the specified
/// FileEntry has been entered.
void IncrementIncludeCount(const FileEntry *File) {
++getFileInfo(File).NumIncludes;
}
- /// \brief Mark the specified file as having a controlling macro.
+ /// Mark the specified file as having a controlling macro.
///
/// This is used by the multiple-include optimization to eliminate
/// no-op \#includes.
@@ -465,12 +467,12 @@ public:
getFileInfo(File).ControllingMacro = ControllingMacro;
}
- /// \brief Return true if this is the first time encountering this header.
+ /// Return true if this is the first time encountering this header.
bool FirstTimeLexingFile(const FileEntry *File) {
return getFileInfo(File).NumIncludes == 1;
}
- /// \brief Determine whether this file is intended to be safe from
+ /// Determine whether this file is intended to be safe from
/// multiple inclusions, e.g., it has \#pragma once or a controlling
/// macro.
///
@@ -481,10 +483,10 @@ public:
/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
const HeaderMap *CreateHeaderMap(const FileEntry *FE);
- /// \brief Get filenames for all registered header maps.
+ /// Get filenames for all registered header maps.
void getHeaderMapFileNames(SmallVectorImpl<std::string> &Names) const;
- /// \brief Retrieve the name of the cached module file that should be used
+ /// Retrieve the name of the cached module file that should be used
/// to load the given module.
///
/// \param Module The module whose module file name will be returned.
@@ -493,7 +495,7 @@ public:
/// or an empty string if this module does not correspond to any module file.
std::string getCachedModuleFileName(Module *Module);
- /// \brief Retrieve the name of the prebuilt module file that should be used
+ /// Retrieve the name of the prebuilt module file that should be used
/// to load a module with the given name.
///
/// \param ModuleName The module whose module file name will be returned.
@@ -506,7 +508,7 @@ public:
std::string getPrebuiltModuleFileName(StringRef ModuleName,
bool FileMapOnly = false);
- /// \brief Retrieve the name of the (to-be-)cached module file that should
+ /// Retrieve the name of the (to-be-)cached module file that should
/// be used to load a module with the given name.
///
/// \param ModuleName The module whose module file name will be returned.
@@ -519,7 +521,7 @@ public:
std::string getCachedModuleFileName(StringRef ModuleName,
StringRef ModuleMapPath);
- /// \brief Lookup a module Search for a module with the given name.
+ /// Lookup a module Search for a module with the given name.
///
/// \param ModuleName The name of the module we're looking for.
///
@@ -527,17 +529,21 @@ public:
/// search directories to produce a module definition. If not, this lookup
/// will only return an already-known module.
///
+ /// \param AllowExtraModuleMapSearch Whether we allow to search modulemaps
+ /// in subdirectories.
+ ///
/// \returns The module with the given name.
- Module *lookupModule(StringRef ModuleName, bool AllowSearch = true);
+ Module *lookupModule(StringRef ModuleName, bool AllowSearch = true,
+ bool AllowExtraModuleMapSearch = false);
- /// \brief Try to find a module map file in the given directory, returning
+ /// Try to find a module map file in the given directory, returning
/// \c nullptr if none is found.
const FileEntry *lookupModuleMapFile(const DirectoryEntry *Dir,
bool IsFramework);
void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
- /// \brief Determine whether there is a module map that may map the header
+ /// Determine whether there is a module map that may map the header
/// with the given file name to a (sub)module.
/// Always returns false if modules are disabled.
///
@@ -551,14 +557,14 @@ public:
bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root,
bool IsSystem);
- /// \brief Retrieve the module that corresponds to the given file, if any.
+ /// Retrieve the module that corresponds to the given file, if any.
///
/// \param File The header that we wish to map to a module.
/// \param AllowTextual Whether we want to find textual headers too.
ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File,
bool AllowTextual = false) const;
- /// \brief Read the contents of the given module map file.
+ /// Read the contents of the given module map file.
///
/// \param File The module map file.
/// \param IsSystem Whether this file is in a system header directory.
@@ -575,16 +581,16 @@ public:
FileID ID = FileID(), unsigned *Offset = nullptr,
StringRef OriginalModuleMapFile = StringRef());
- /// \brief Collect the set of all known, top-level modules.
+ /// Collect the set of all known, top-level modules.
///
/// \param Modules Will be filled with the set of known, top-level modules.
void collectAllModules(SmallVectorImpl<Module *> &Modules);
- /// \brief Load all known, top-level system modules.
+ /// Load all known, top-level system modules.
void loadTopLevelSystemModules();
private:
- /// \brief Lookup a module with the given module name and search-name.
+ /// Lookup a module with the given module name and search-name.
///
/// \param ModuleName The name of the module we're looking for.
///
@@ -593,10 +599,14 @@ private:
/// but for compatibility with some buggy frameworks, additional attempts
/// may be made to find the module under a related-but-different search-name.
///
+ /// \param AllowExtraModuleMapSearch Whether we allow to search modulemaps
+ /// in subdirectories.
+ ///
/// \returns The module named ModuleName.
- Module *lookupModule(StringRef ModuleName, StringRef SearchName);
+ Module *lookupModule(StringRef ModuleName, StringRef SearchName,
+ bool AllowExtraModuleMapSearch = false);
- /// \brief Retrieve a module with the given name, which may be part of the
+ /// Retrieve a module with the given name, which may be part of the
/// given framework.
///
/// \param Name The name of the module to retrieve.
@@ -611,11 +621,11 @@ private:
const DirectoryEntry *Dir,
bool IsSystem);
- /// \brief Load all of the module maps within the immediate subdirectories
+ /// Load all of the module maps within the immediate subdirectories
/// of the given search directory.
void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
- /// \brief Find and suggest a usable module for the given file.
+ /// Find and suggest a usable module for the given file.
///
/// \return \c true if the file can be used, \c false if we are not permitted to
/// find this file due to requirements from \p RequestingModule.
@@ -625,7 +635,7 @@ private:
ModuleMap::KnownHeader *SuggestedModule,
bool IsSystemHeaderDir);
- /// \brief Find and suggest a usable module for the given file, which is part of
+ /// Find and suggest a usable module for the given file, which is part of
/// the specified framework.
///
/// \return \c true if the file can be used, \c false if we are not permitted to
@@ -634,7 +644,7 @@ private:
const FileEntry *File, StringRef FrameworkDir, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework);
- /// \brief Look up the file with the specified name and determine its owning
+ /// Look up the file with the specified name and determine its owning
/// module.
const FileEntry *
getFileAndSuggestModule(StringRef FileName, SourceLocation IncludeLoc,
@@ -643,19 +653,19 @@ private:
ModuleMap::KnownHeader *SuggestedModule);
public:
- /// \brief Retrieve the module map.
+ /// Retrieve the module map.
ModuleMap &getModuleMap() { return ModMap; }
- /// \brief Retrieve the module map.
+ /// Retrieve the module map.
const ModuleMap &getModuleMap() const { return ModMap; }
unsigned header_file_size() const { return FileInfo.size(); }
- /// \brief Return the HeaderFileInfo structure for the specified FileEntry,
+ /// Return the HeaderFileInfo structure for the specified FileEntry,
/// in preparation for updating it in some way.
HeaderFileInfo &getFileInfo(const FileEntry *FE);
- /// \brief Return the HeaderFileInfo structure for the specified FileEntry,
+ /// Return the HeaderFileInfo structure for the specified FileEntry,
/// if it has ever been filled in.
/// \param WantExternal Whether the caller wants purely-external header file
/// info (where \p External is true).
@@ -691,10 +701,10 @@ public:
search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
- /// \brief Retrieve a uniqued framework name.
+ /// Retrieve a uniqued framework name.
StringRef getUniqueFrameworkName(StringRef Framework);
-
- /// \brief Suggest a path by which the specified file could be found, for
+
+ /// Suggest a path by which the specified file could be found, for
/// use in diagnostics to suggest a #include.
///
/// \param IsSystem If non-null, filled in to indicate whether the suggested
@@ -702,23 +712,32 @@ public:
std::string suggestPathToFileForDiagnostics(const FileEntry *File,
bool *IsSystem = nullptr);
+ /// Suggest a path by which the specified file could be found, for
+ /// use in diagnostics to suggest a #include.
+ ///
+ /// \param WorkingDir If non-empty, this will be prepended to search directory
+ /// paths that are relative.
+ std::string suggestPathToFileForDiagnostics(llvm::StringRef File,
+ llvm::StringRef WorkingDir,
+ bool *IsSystem = nullptr);
+
void PrintStats();
size_t getTotalMemory() const;
private:
- /// \brief Describes what happened when we tried to load a module map file.
+ /// Describes what happened when we tried to load a module map file.
enum LoadModuleMapResult {
- /// \brief The module map file had already been loaded.
+ /// The module map file had already been loaded.
LMM_AlreadyLoaded,
- /// \brief The module map file was loaded by this invocation.
+ /// The module map file was loaded by this invocation.
LMM_NewlyLoaded,
- /// \brief There is was directory with the given name.
+ /// There is was directory with the given name.
LMM_NoDirectory,
- /// \brief There was either no module map file or the module map file was
+ /// There was either no module map file or the module map file was
/// invalid.
LMM_InvalidModuleMap
};
@@ -729,7 +748,7 @@ private:
FileID ID = FileID(),
unsigned *Offset = nullptr);
- /// \brief Try to load the module map file in the given directory.
+ /// Try to load the module map file in the given directory.
///
/// \param DirName The name of the directory where we will look for a module
/// map file.
@@ -741,7 +760,7 @@ private:
LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem,
bool IsFramework);
- /// \brief Try to load the module map file in the given directory.
+ /// Try to load the module map file in the given directory.
///
/// \param Dir The directory where we will look for a module map file.
/// \param IsSystem Whether this is a system header directory.
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index 937ad9863db37..298179e91a6fd 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -108,32 +108,32 @@ public:
/// etc.).
std::string ResourceDir;
- /// \brief The directory used for the module cache.
+ /// The directory used for the module cache.
std::string ModuleCachePath;
- /// \brief The directory used for a user build.
+ /// The directory used for a user build.
std::string ModuleUserBuildPath;
- /// \brief The mapping of module names to prebuilt module files.
+ /// The mapping of module names to prebuilt module files.
std::map<std::string, std::string> PrebuiltModuleFiles;
- /// \brief The directories used to load prebuilt module files.
+ /// The directories used to load prebuilt module files.
std::vector<std::string> PrebuiltModulePaths;
/// The module/pch container format.
std::string ModuleFormat;
- /// \brief Whether we should disable the use of the hash string within the
+ /// Whether we should disable the use of the hash string within the
/// module cache.
///
/// Note: Only used for testing!
unsigned DisableModuleHash : 1;
- /// \brief Implicit module maps. This option is enabld by default when
+ /// Implicit module maps. This option is enabld by default when
/// modules is enabled.
unsigned ImplicitModuleMaps : 1;
- /// \brief Set the 'home directory' of a module map file to the current
+ /// Set the 'home directory' of a module map file to the current
/// working directory (or the home directory of the module map file that
/// contained the 'extern module' directive importing this module map file
/// if any) rather than the directory containing the module map file.
@@ -142,7 +142,7 @@ public:
/// file.
unsigned ModuleMapFileHomeIsCwd : 1;
- /// \brief The interval (in seconds) between pruning operations.
+ /// The interval (in seconds) between pruning operations.
///
/// This operation is expensive, because it requires Clang to walk through
/// the directory structure of the module cache, stat()'ing and removing
@@ -151,7 +151,7 @@ public:
/// The default value is large, e.g., the operation runs once a week.
unsigned ModuleCachePruneInterval = 7 * 24 * 60 * 60;
- /// \brief The time (in seconds) after which an unused module file will be
+ /// The time (in seconds) after which an unused module file will be
/// considered unused and will, therefore, be pruned.
///
/// When the module cache is pruned, any module file that has not been
@@ -160,17 +160,17 @@ public:
/// regenerated often.
unsigned ModuleCachePruneAfter = 31 * 24 * 60 * 60;
- /// \brief The time in seconds when the build session started.
+ /// The time in seconds when the build session started.
///
/// This time is used by other optimizations in header search and module
/// loading.
uint64_t BuildSessionTimestamp = 0;
- /// \brief The set of macro names that should be ignored for the purposes
+ /// The set of macro names that should be ignored for the purposes
/// of computing the module hash.
llvm::SmallSetVector<llvm::CachedHashString, 16> ModulesIgnoreMacros;
- /// \brief The set of user-provided virtual filesystem overlay files.
+ /// The set of user-provided virtual filesystem overlay files.
std::vector<std::string> VFSOverlayFiles;
/// Include the compiler builtin includes.
@@ -188,12 +188,12 @@ public:
/// Whether header search information should be output as for -v.
unsigned Verbose : 1;
- /// \brief If true, skip verifying input files used by modules if the
+ /// If true, skip verifying input files used by modules if the
/// module was already verified during this build session (see
/// \c BuildSessionTimestamp).
unsigned ModulesValidateOncePerBuildSession : 1;
- /// \brief Whether to validate system input files when a module is loaded.
+ /// Whether to validate system input files when a module is loaded.
unsigned ModulesValidateSystemHeaders : 1;
/// Whether the module includes debug information (-gmodules).
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index d58849654cb83..624151ef877b0 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -57,10 +57,10 @@ enum ConflictMarkerKind {
/// PreprocessorOptions::PrecompiledPreambleBytes.
/// The preamble includes the BOM, if any.
struct PreambleBounds {
- /// \brief Size of the preamble in bytes.
+ /// Size of the preamble in bytes.
unsigned Size;
- /// \brief Whether the preamble ends at the start of a new line.
+ /// Whether the preamble ends at the start of a new line.
///
/// Used to inform the lexer as to whether it's starting at the beginning of
/// a line after skipping the preamble.
@@ -263,7 +263,7 @@ public:
return getSourceLocation(BufferPtr);
}
- /// \brief Return the current location in the buffer.
+ /// Return the current location in the buffer.
const char *getBufferLocation() const { return BufferPtr; }
/// Stringify - Convert the specified string into a C string by i) escaping
@@ -322,29 +322,39 @@ public:
const SourceManager &SM,
const LangOptions &LangOpts);
- /// \brief Relex the token at the specified location.
+ /// Relex the token at the specified location.
/// \returns true if there was a failure, false on success.
static bool getRawToken(SourceLocation Loc, Token &Result,
const SourceManager &SM,
const LangOptions &LangOpts,
bool IgnoreWhiteSpace = false);
- /// \brief Given a location any where in a source buffer, find the location
+ /// Given a location any where in a source buffer, find the location
/// that corresponds to the beginning of the token in which the original
/// source location lands.
static SourceLocation GetBeginningOfToken(SourceLocation Loc,
const SourceManager &SM,
const LangOptions &LangOpts);
+ /// Get the physical length (including trigraphs and escaped newlines) of the
+ /// first \p Characters characters of the token starting at TokStart.
+ static unsigned getTokenPrefixLength(SourceLocation TokStart,
+ unsigned Characters,
+ const SourceManager &SM,
+ const LangOptions &LangOpts);
+
/// AdvanceToTokenCharacter - If the current SourceLocation specifies a
/// location at the start of a token, return a new location that specifies a
/// character within the token. This handles trigraphs and escaped newlines.
static SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
- unsigned Character,
+ unsigned Characters,
const SourceManager &SM,
- const LangOptions &LangOpts);
+ const LangOptions &LangOpts) {
+ return TokStart.getLocWithOffset(
+ getTokenPrefixLength(TokStart, Characters, SM, LangOpts));
+ }
- /// \brief Computes the source location just past the end of the
+ /// Computes the source location just past the end of the
/// token at this source location.
///
/// This routine can be used to produce a source location that
@@ -363,7 +373,7 @@ public:
const SourceManager &SM,
const LangOptions &LangOpts);
- /// \brief Given a token range, produce a corresponding CharSourceRange that
+ /// Given a token range, produce a corresponding CharSourceRange that
/// is not a token range. This allows the source range to be used by
/// components that don't have access to the lexer and thus can't find the
/// end of the range for themselves.
@@ -383,7 +393,7 @@ public:
: Range;
}
- /// \brief Returns true if the given MacroID location points at the first
+ /// Returns true if the given MacroID location points at the first
/// token of the macro expansion.
///
/// \param MacroBegin If non-null and function returns true, it is set to
@@ -393,7 +403,7 @@ public:
const LangOptions &LangOpts,
SourceLocation *MacroBegin = nullptr);
- /// \brief Returns true if the given MacroID location points at the last
+ /// Returns true if the given MacroID location points at the last
/// token of the macro expansion.
///
/// \param MacroEnd If non-null and function returns true, it is set to
@@ -403,7 +413,7 @@ public:
const LangOptions &LangOpts,
SourceLocation *MacroEnd = nullptr);
- /// \brief Accepts a range and returns a character range with file locations.
+ /// Accepts a range and returns a character range with file locations.
///
/// Returns a null range if a part of the range resides inside a macro
/// expansion or the range does not reside on the same FileID.
@@ -433,13 +443,13 @@ public:
const SourceManager &SM,
const LangOptions &LangOpts);
- /// \brief Returns a string for the source that the range encompasses.
+ /// Returns a string for the source that the range encompasses.
static StringRef getSourceText(CharSourceRange Range,
const SourceManager &SM,
const LangOptions &LangOpts,
bool *Invalid = nullptr);
- /// \brief Retrieve the name of the immediate macro expansion.
+ /// Retrieve the name of the immediate macro expansion.
///
/// This routine starts from a source location, and finds the name of the macro
/// responsible for its immediate expansion. It looks through any intervening
@@ -450,7 +460,7 @@ public:
const SourceManager &SM,
const LangOptions &LangOpts);
- /// \brief Retrieve the name of the immediate macro expansion.
+ /// Retrieve the name of the immediate macro expansion.
///
/// This routine starts from a source location, and finds the name of the
/// macro responsible for its immediate expansion. It looks through any
@@ -470,7 +480,7 @@ public:
static StringRef getImmediateMacroNameForDiagnostics(
SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts);
- /// \brief Compute the preamble of the given file.
+ /// Compute the preamble of the given file.
///
/// The preamble of a file contains the initial comments, include directives,
/// and other preprocessor directives that occur before the code in this
@@ -496,7 +506,7 @@ public:
const SourceManager &SM,
const LangOptions &LangOpts);
- /// \brief Checks that the given token is the first token that occurs after
+ /// Checks that the given token is the first token that occurs after
/// the given location (this excludes comments and whitespace). Returns the
/// location immediately after the specified token. If the token is not found
/// or the location is inside a macro, the returned source location will be
@@ -507,10 +517,10 @@ public:
const LangOptions &LangOpts,
bool SkipTrailingWhitespaceAndNewLine);
- /// \brief Returns true if the given character could appear in an identifier.
+ /// Returns true if the given character could appear in an identifier.
static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts);
- /// \brief Checks whether new line pointed by Str is preceded by escape
+ /// Checks whether new line pointed by Str is preceded by escape
/// sequence.
static bool isNewLineEscaped(const char *BufferStart, const char *Str);
@@ -716,7 +726,7 @@ private:
/// invalid.
uint32_t tryReadUCN(const char *&CurPtr, const char *SlashLoc, Token *Tok);
- /// \brief Try to consume a UCN as part of an identifier at the current
+ /// Try to consume a UCN as part of an identifier at the current
/// location.
/// \param CurPtr Initially points to the range of characters in the source
/// buffer containing the '\'. Updated to point past the end of
@@ -730,7 +740,7 @@ private:
bool tryConsumeIdentifierUCN(const char *&CurPtr, unsigned Size,
Token &Result);
- /// \brief Try to consume an identifier character encoded in UTF-8.
+ /// Try to consume an identifier character encoded in UTF-8.
/// \param CurPtr Points to the start of the (potential) UTF-8 code unit
/// sequence. On success, updated to point past the end of it.
/// \return \c true if a UTF-8 sequence mapping to an acceptable identifier
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index cc9223eb7dbb3..1b6bf6bcffb0e 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -50,7 +50,7 @@ class NumericLiteralParser {
unsigned radix;
- bool saw_exponent, saw_period, saw_ud_suffix;
+ bool saw_exponent, saw_period, saw_ud_suffix, saw_fixed_point_suffix;
SmallString<32> UDSuffixBuf;
@@ -69,11 +69,16 @@ public:
bool isFloat128 : 1; // 1.0q
uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64.
+ bool isFract : 1; // 1.0hr/r/lr/uhr/ur/ulr
+ bool isAccum : 1; // 1.0hk/k/lk/uhk/uk/ulk
+
+ bool isFixedPointLiteral() const { return saw_fixed_point_suffix; }
+
bool isIntegerLiteral() const {
- return !saw_period && !saw_exponent;
+ return !saw_period && !saw_exponent && !isFixedPointLiteral();
}
bool isFloatingLiteral() const {
- return saw_period || saw_exponent;
+ return (saw_period || saw_exponent) && !isFixedPointLiteral();
}
bool hasUDSuffix() const {
@@ -105,6 +110,12 @@ public:
/// literal exactly, and false otherwise.
llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result);
+ /// GetFixedPointValue - Convert this numeric literal value into a
+ /// scaled integer that represents this value. Returns true if an overflow
+ /// occurred when calculating the integral part of the scaled integer or
+ /// calculating the digit sequence of the exponent.
+ bool GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale);
+
private:
void ParseNumberStartingWithZero(SourceLocation TokLoc);
@@ -112,7 +123,7 @@ private:
static bool isDigitSeparator(char C) { return C == '\''; }
- /// \brief Determine whether the sequence of characters [Start, End) contains
+ /// Determine whether the sequence of characters [Start, End) contains
/// any real digits (not digit separators).
bool containsDigits(const char *Start, const char *End) {
return Start != End && (Start + 1 != End || !isDigitSeparator(Start[0]));
@@ -120,7 +131,7 @@ private:
enum CheckSeparatorKind { CSK_BeforeDigits, CSK_AfterDigits };
- /// \brief Ensure that we don't have a digit separator here.
+ /// Ensure that we don't have a digit separator here.
void checkSeparator(SourceLocation TokLoc, const char *Pos,
CheckSeparatorKind IsAfterDigits);
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index 3029294209ec5..13e5313a9c301 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Defines the clang::MacroInfo and clang::MacroDirective classes.
+/// Defines the clang::MacroInfo and clang::MacroDirective classes.
//
//===----------------------------------------------------------------------===//
@@ -34,20 +34,20 @@ class Module;
class Preprocessor;
class SourceManager;
-/// \brief Encapsulates the data about a macro definition (e.g. its tokens).
+/// Encapsulates the data about a macro definition (e.g. its tokens).
///
/// There's an instance of this class for every #define.
class MacroInfo {
//===--------------------------------------------------------------------===//
// State set when the macro is defined.
- /// \brief The location the macro is defined.
+ /// The location the macro is defined.
SourceLocation Location;
- /// \brief The location of the last token in the macro.
+ /// The location of the last token in the macro.
SourceLocation EndLocation;
- /// \brief The list of arguments for a function-like macro.
+ /// The list of arguments for a function-like macro.
///
/// ParameterList points to the first of NumParameters pointers.
///
@@ -58,61 +58,61 @@ class MacroInfo {
/// \see ParameterList
unsigned NumParameters = 0;
- /// \brief This is the list of tokens that the macro is defined to.
+ /// This is the list of tokens that the macro is defined to.
SmallVector<Token, 8> ReplacementTokens;
- /// \brief Length in characters of the macro definition.
+ /// Length in characters of the macro definition.
mutable unsigned DefinitionLength;
mutable bool IsDefinitionLengthCached : 1;
- /// \brief True if this macro is function-like, false if it is object-like.
+ /// True if this macro is function-like, false if it is object-like.
bool IsFunctionLike : 1;
- /// \brief True if this macro is of the form "#define X(...)" or
+ /// True if this macro is of the form "#define X(...)" or
/// "#define X(Y,Z,...)".
///
/// The __VA_ARGS__ token should be replaced with the contents of "..." in an
/// invocation.
bool IsC99Varargs : 1;
- /// \brief True if this macro is of the form "#define X(a...)".
+ /// True if this macro is of the form "#define X(a...)".
///
/// The "a" identifier in the replacement list will be replaced with all
/// arguments of the macro starting with the specified one.
bool IsGNUVarargs : 1;
- /// \brief True if this macro requires processing before expansion.
+ /// True if this macro requires processing before expansion.
///
/// This is the case for builtin macros such as __LINE__, so long as they have
/// not been redefined, but not for regular predefined macros from the
/// "<built-in>" memory buffer (see Preprocessing::getPredefinesFileID).
bool IsBuiltinMacro : 1;
- /// \brief Whether this macro contains the sequence ", ## __VA_ARGS__"
+ /// Whether this macro contains the sequence ", ## __VA_ARGS__"
bool HasCommaPasting : 1;
//===--------------------------------------------------------------------===//
// State that changes as the macro is used.
- /// \brief True if we have started an expansion of this macro already.
+ /// True if we have started an expansion of this macro already.
///
/// This disables recursive expansion, which would be quite bad for things
/// like \#define A A.
bool IsDisabled : 1;
- /// \brief True if this macro is either defined in the main file and has
+ /// True if this macro is either defined in the main file and has
/// been used, or if it is not defined in the main file.
///
/// This is used to emit -Wunused-macros diagnostics.
bool IsUsed : 1;
- /// \brief True if this macro can be redefined without emitting a warning.
+ /// True if this macro can be redefined without emitting a warning.
bool IsAllowRedefinitionsWithoutWarning : 1;
- /// \brief Must warn if the macro is unused at the end of translation unit.
+ /// Must warn if the macro is unused at the end of translation unit.
bool IsWarnIfUnused : 1;
- /// \brief Whether this macro was used as header guard.
+ /// Whether this macro was used as header guard.
bool UsedForHeaderGuard : 1;
// Only the Preprocessor gets to create and destroy these.
@@ -120,23 +120,23 @@ class MacroInfo {
~MacroInfo() = default;
public:
- /// \brief Return the location that the macro was defined at.
+ /// Return the location that the macro was defined at.
SourceLocation getDefinitionLoc() const { return Location; }
- /// \brief Set the location of the last token in the macro.
+ /// Set the location of the last token in the macro.
void setDefinitionEndLoc(SourceLocation EndLoc) { EndLocation = EndLoc; }
- /// \brief Return the location of the last token in the macro.
+ /// Return the location of the last token in the macro.
SourceLocation getDefinitionEndLoc() const { return EndLocation; }
- /// \brief Get length in characters of the macro definition.
+ /// Get length in characters of the macro definition.
unsigned getDefinitionLength(const SourceManager &SM) const {
if (IsDefinitionLengthCached)
return DefinitionLength;
return getDefinitionLengthSlow(SM);
}
- /// \brief Return true if the specified macro definition is equal to
+ /// Return true if the specified macro definition is equal to
/// this macro in spelling, arguments, and whitespace.
///
/// \param Syntactically if true, the macro definitions can be identical even
@@ -146,21 +146,21 @@ public:
bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
bool Syntactically) const;
- /// \brief Set or clear the isBuiltinMacro flag.
+ /// Set or clear the isBuiltinMacro flag.
void setIsBuiltinMacro(bool Val = true) { IsBuiltinMacro = Val; }
- /// \brief Set the value of the IsUsed flag.
+ /// Set the value of the IsUsed flag.
void setIsUsed(bool Val) { IsUsed = Val; }
- /// \brief Set the value of the IsAllowRedefinitionsWithoutWarning flag.
+ /// Set the value of the IsAllowRedefinitionsWithoutWarning flag.
void setIsAllowRedefinitionsWithoutWarning(bool Val) {
IsAllowRedefinitionsWithoutWarning = Val;
}
- /// \brief Set the value of the IsWarnIfUnused flag.
+ /// Set the value of the IsWarnIfUnused flag.
void setIsWarnIfUnused(bool val) { IsWarnIfUnused = val; }
- /// \brief Set the specified list of identifiers as the parameter list for
+ /// Set the specified list of identifiers as the parameter list for
/// this macro.
void setParameterList(ArrayRef<IdentifierInfo *> List,
llvm::BumpPtrAllocator &PPAllocator) {
@@ -185,7 +185,7 @@ public:
return ArrayRef<const IdentifierInfo *>(ParameterList, NumParameters);
}
- /// \brief Return the parameter number of the specified identifier,
+ /// Return the parameter number of the specified identifier,
/// or -1 if the identifier is not a formal parameter identifier.
int getParameterNum(const IdentifierInfo *Arg) const {
for (param_iterator I = param_begin(), E = param_end(); I != E; ++I)
@@ -207,7 +207,7 @@ public:
bool isGNUVarargs() const { return IsGNUVarargs; }
bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; }
- /// \brief Return true if this macro requires processing before expansion.
+ /// Return true if this macro requires processing before expansion.
///
/// This is true only for builtin macro, such as \__LINE__, whose values
/// are not given by fixed textual expansions. Regular predefined macros
@@ -218,19 +218,19 @@ public:
bool hasCommaPasting() const { return HasCommaPasting; }
void setHasCommaPasting() { HasCommaPasting = true; }
- /// \brief Return false if this macro is defined in the main file and has
+ /// Return false if this macro is defined in the main file and has
/// not yet been used.
bool isUsed() const { return IsUsed; }
- /// \brief Return true if this macro can be redefined without warning.
+ /// Return true if this macro can be redefined without warning.
bool isAllowRedefinitionsWithoutWarning() const {
return IsAllowRedefinitionsWithoutWarning;
}
- /// \brief Return true if we should emit a warning if the macro is unused.
+ /// Return true if we should emit a warning if the macro is unused.
bool isWarnIfUnused() const { return IsWarnIfUnused; }
- /// \brief Return the number of tokens that this macro expands to.
+ /// Return the number of tokens that this macro expands to.
unsigned getNumTokens() const { return ReplacementTokens.size(); }
const Token &getReplacementToken(unsigned Tok) const {
@@ -245,7 +245,7 @@ public:
bool tokens_empty() const { return ReplacementTokens.empty(); }
ArrayRef<Token> tokens() const { return ReplacementTokens; }
- /// \brief Add the specified token to the replacement text for the macro.
+ /// Add the specified token to the replacement text for the macro.
void AddTokenToBody(const Token &Tok) {
assert(
!IsDefinitionLengthCached &&
@@ -253,7 +253,7 @@ public:
ReplacementTokens.push_back(Tok);
}
- /// \brief Return true if this macro is enabled.
+ /// Return true if this macro is enabled.
///
/// In other words, that we are not currently in an expansion of this macro.
bool isEnabled() const { return !IsDisabled; }
@@ -268,7 +268,7 @@ public:
IsDisabled = true;
}
- /// \brief Determine whether this macro was used for a header guard.
+ /// Determine whether this macro was used for a header guard.
bool isUsedForHeaderGuard() const { return UsedForHeaderGuard; }
void setUsedForHeaderGuard(bool Val) { UsedForHeaderGuard = Val; }
@@ -281,7 +281,7 @@ private:
unsigned getDefinitionLengthSlow(const SourceManager &SM) const;
};
-/// \brief Encapsulates changes to the "macros namespace" (the location where
+/// Encapsulates changes to the "macros namespace" (the location where
/// the macro name became active, the location where it was undefined, etc.).
///
/// MacroDirectives, associated with an identifier, are used to model the macro
@@ -297,20 +297,20 @@ public:
};
protected:
- /// \brief Previous macro directive for the same identifier, or nullptr.
+ /// Previous macro directive for the same identifier, or nullptr.
MacroDirective *Previous = nullptr;
SourceLocation Loc;
- /// \brief MacroDirective kind.
+ /// MacroDirective kind.
unsigned MDKind : 2;
- /// \brief True if the macro directive was loaded from a PCH file.
+ /// True if the macro directive was loaded from a PCH file.
unsigned IsFromPCH : 1;
// Used by VisibilityMacroDirective ----------------------------------------//
- /// \brief Whether the macro has public visibility (when described in a
+ /// Whether the macro has public visibility (when described in a
/// module).
unsigned IsPublic : 1;
@@ -322,16 +322,16 @@ public:
SourceLocation getLocation() const { return Loc; }
- /// \brief Set previous definition of the macro with the same name.
+ /// Set previous definition of the macro with the same name.
void setPrevious(MacroDirective *Prev) { Previous = Prev; }
- /// \brief Get previous definition of the macro with the same name.
+ /// Get previous definition of the macro with the same name.
const MacroDirective *getPrevious() const { return Previous; }
- /// \brief Get previous definition of the macro with the same name.
+ /// Get previous definition of the macro with the same name.
MacroDirective *getPrevious() { return Previous; }
- /// \brief Return true if the macro directive was loaded from a PCH file.
+ /// Return true if the macro directive was loaded from a PCH file.
bool isFromPCH() const { return IsFromPCH; }
void setIsFromPCH() { IsFromPCH = true; }
@@ -374,7 +374,7 @@ public:
}
};
- /// \brief Traverses the macro directives history and returns the next
+ /// Traverses the macro directives history and returns the next
/// macro definition directive along with info about its undefined location
/// (if there is one) and if it is public or private.
DefInfo getDefinition();
@@ -393,7 +393,7 @@ public:
}
MacroInfo *getMacroInfo() { return getDefinition().getMacroInfo(); }
- /// \brief Find macro definition active in the specified source location. If
+ /// Find macro definition active in the specified source location. If
/// this macro was not defined there, return NULL.
const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const;
@@ -402,7 +402,7 @@ public:
static bool classof(const MacroDirective *) { return true; }
};
-/// \brief A directive for a defined macro or a macro imported from a module.
+/// A directive for a defined macro or a macro imported from a module.
class DefMacroDirective : public MacroDirective {
MacroInfo *Info;
@@ -414,7 +414,7 @@ public:
explicit DefMacroDirective(MacroInfo *MI)
: DefMacroDirective(MI, MI->getDefinitionLoc()) {}
- /// \brief The data for the macro definition.
+ /// The data for the macro definition.
const MacroInfo *getInfo() const { return Info; }
MacroInfo *getInfo() { return Info; }
@@ -425,7 +425,7 @@ public:
static bool classof(const DefMacroDirective *) { return true; }
};
-/// \brief A directive for an undefined macro.
+/// A directive for an undefined macro.
class UndefMacroDirective : public MacroDirective {
public:
explicit UndefMacroDirective(SourceLocation UndefLoc)
@@ -440,7 +440,7 @@ public:
static bool classof(const UndefMacroDirective *) { return true; }
};
-/// \brief A directive for setting the module visibility of a macro.
+/// A directive for setting the module visibility of a macro.
class VisibilityMacroDirective : public MacroDirective {
public:
explicit VisibilityMacroDirective(SourceLocation Loc, bool Public)
@@ -448,7 +448,7 @@ public:
IsPublic = Public;
}
- /// \brief Determine whether this macro is part of the public API of its
+ /// Determine whether this macro is part of the public API of its
/// module.
bool isPublic() const { return IsPublic; }
@@ -478,7 +478,7 @@ MacroDirective::DefInfo::getPreviousDefinition() {
return DefDirective->getPrevious()->getDefinition();
}
-/// \brief Represents a macro directive exported by a module.
+/// Represents a macro directive exported by a module.
///
/// There's an instance of this class for every macro #define or #undef that is
/// the final directive for a macro name within a module. These entities also
@@ -557,7 +557,7 @@ public:
unsigned getNumOverridingMacros() const { return NumOverriddenBy; }
};
-/// \brief A description of the current definition of a macro.
+/// A description of the current definition of a macro.
///
/// The definition of a macro comprises a set of (at least one) defining
/// entities, which are either local MacroDirectives or imported ModuleMacros.
@@ -571,12 +571,12 @@ public:
bool IsAmbiguous)
: LatestLocalAndAmbiguous(MD, IsAmbiguous), ModuleMacros(MMs) {}
- /// \brief Determine whether there is a definition of this macro.
+ /// Determine whether there is a definition of this macro.
explicit operator bool() const {
return getLocalDirective() || !ModuleMacros.empty();
}
- /// \brief Get the MacroInfo that should be used for this definition.
+ /// Get the MacroInfo that should be used for this definition.
MacroInfo *getMacroInfo() const {
if (!ModuleMacros.empty())
return ModuleMacros.back()->getMacroInfo();
@@ -585,16 +585,16 @@ public:
return nullptr;
}
- /// \brief \c true if the definition is ambiguous, \c false otherwise.
+ /// \c true if the definition is ambiguous, \c false otherwise.
bool isAmbiguous() const { return LatestLocalAndAmbiguous.getInt(); }
- /// \brief Get the latest non-imported, non-\#undef'd macro definition
+ /// Get the latest non-imported, non-\#undef'd macro definition
/// for this macro.
DefMacroDirective *getLocalDirective() const {
return LatestLocalAndAmbiguous.getPointer();
}
- /// \brief Get the active module macros for this macro.
+ /// Get the active module macros for this macro.
ArrayRef<ModuleMacro *> getModuleMacros() const { return ModuleMacros; }
template <typename Fn> void forAllDefinitions(Fn F) const {
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
index 30ea583b71e0b..a2766fa35984f 100644
--- a/include/clang/Lex/ModuleLoader.h
+++ b/include/clang/Lex/ModuleLoader.h
@@ -28,11 +28,11 @@ namespace clang {
class GlobalModuleIndex;
class IdentifierInfo;
-/// \brief A sequence of identifier/location pairs used to describe a particular
+/// A sequence of identifier/location pairs used to describe a particular
/// module or submodule, e.g., std.vector.
using ModuleIdPath = ArrayRef<std::pair<IdentifierInfo *, SourceLocation>>;
-/// \brief Describes the result of attempting to load a module.
+/// Describes the result of attempting to load a module.
class ModuleLoadResult {
public:
enum LoadResultKind {
@@ -55,18 +55,18 @@ public:
operator Module *() const { return Storage.getPointer(); }
- /// \brief Determines whether the module, which failed to load, was
+ /// Determines whether the module, which failed to load, was
/// actually a submodule that we expected to see (based on implying the
/// submodule from header structure), but didn't materialize in the actual
/// module.
bool isMissingExpected() const { return Storage.getInt() == MissingExpected; }
- /// \brief Determines whether the module failed to load due to a configuration
+ /// Determines whether the module failed to load due to a configuration
/// mismatch with an explicitly-named .pcm file from the command line.
bool isConfigMismatch() const { return Storage.getInt() == ConfigMismatch; }
};
-/// \brief Abstract interface for a module loader.
+/// Abstract interface for a module loader.
///
/// This abstract interface describes a module loader, which is responsible
/// for resolving a module name (e.g., "std") to an actual module file, and
@@ -81,17 +81,17 @@ public:
virtual ~ModuleLoader();
- /// \brief Returns true if this instance is building a module.
+ /// Returns true if this instance is building a module.
bool buildingModule() const {
return BuildingModule;
}
- /// \brief Flag indicating whether this instance is building a module.
+ /// Flag indicating whether this instance is building a module.
void setBuildingModule(bool BuildingModuleFlag) {
BuildingModule = BuildingModuleFlag;
}
- /// \brief Attempt to load the given module.
+ /// Attempt to load the given module.
///
/// This routine attempts to load the module described by the given
/// parameters.
@@ -125,12 +125,12 @@ public:
virtual void loadModuleFromSource(SourceLocation Loc, StringRef ModuleName,
StringRef Source) = 0;
- /// \brief Make the given module visible.
+ /// Make the given module visible.
virtual void makeModuleVisible(Module *Mod,
Module::NameVisibilityKind Visibility,
SourceLocation ImportLoc) = 0;
- /// \brief Load, create, or return global module.
+ /// Load, create, or return global module.
/// This function returns an existing global module index, if one
/// had already been loaded or created, or loads one if it
/// exists, or creates one if it doesn't exist.
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 41ed8e49b6c1d..577f4008978ea 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
@@ -41,13 +42,13 @@ class FileManager;
class HeaderSearch;
class SourceManager;
-/// \brief A mechanism to observe the actions of the module map parser as it
+/// A mechanism to observe the actions of the module map parser as it
/// reads module map files.
class ModuleMapCallbacks {
public:
virtual ~ModuleMapCallbacks() = default;
- /// \brief Called when a module map file has been read.
+ /// Called when a module map file has been read.
///
/// \param FileStart A SourceLocation referring to the start of the file's
/// contents.
@@ -56,12 +57,12 @@ public:
virtual void moduleMapFileRead(SourceLocation FileStart,
const FileEntry &File, bool IsSystem) {}
- /// \brief Called when a header is added during module map parsing.
+ /// Called when a header is added during module map parsing.
///
/// \param Filename The header file itself.
virtual void moduleMapAddHeader(StringRef Filename) {}
- /// \brief Called when an umbrella header is added during module map parsing.
+ /// Called when an umbrella header is added during module map parsing.
///
/// \param FileMgr FileManager instance
/// \param Header The umbrella header to collect.
@@ -78,11 +79,11 @@ class ModuleMap {
llvm::SmallVector<std::unique_ptr<ModuleMapCallbacks>, 1> Callbacks;
- /// \brief The directory used for Clang-supplied, builtin include headers,
+ /// The directory used for Clang-supplied, builtin include headers,
/// such as "stdint.h".
const DirectoryEntry *BuiltinIncludeDir = nullptr;
- /// \brief Language options used to parse the module map itself.
+ /// Language options used to parse the module map itself.
///
/// These are always simple C language options.
LangOptions MMapLangOpts;
@@ -95,22 +96,37 @@ class ModuleMap {
/// transferred if/when we create an enclosing module.
std::unique_ptr<Module> PendingGlobalModule;
- /// \brief The top-level modules that are known.
+ /// The top-level modules that are known.
llvm::StringMap<Module *> Modules;
- /// \brief The number of modules we have created in total.
+ /// Shadow modules created while building this module map.
+ llvm::SmallVector<Module*, 2> ShadowModules;
+
+ /// The number of modules we have created in total.
unsigned NumCreatedModules = 0;
+ /// In case a module has a export_as entry, it might have a pending link
+ /// name to be determined if that module is imported.
+ llvm::StringMap<llvm::StringSet<>> PendingLinkAsModule;
+
public:
- /// \brief Flags describing the role of a module header.
+ /// Use PendingLinkAsModule information to mark top level link names that
+ /// are going to be replaced by export_as aliases.
+ void resolveLinkAsDependencies(Module *Mod);
+
+ /// Make module to use export_as as the link dependency name if enough
+ /// information is available or add it to a pending list otherwise.
+ void addLinkAsDependency(Module *Mod);
+
+ /// Flags describing the role of a module header.
enum ModuleHeaderRole {
- /// \brief This header is normally included in the module.
+ /// This header is normally included in the module.
NormalHeader = 0x0,
- /// \brief This header is included but private.
+ /// This header is included but private.
PrivateHeader = 0x1,
- /// \brief This header is part of the module (for layering purposes) but
+ /// This header is part of the module (for layering purposes) but
/// should be textually included.
TextualHeader = 0x2,
@@ -128,7 +144,7 @@ public:
/// Convert a header role to a kind.
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role);
- /// \brief A header that is known to reside within a given module,
+ /// A header that is known to reside within a given module,
/// whether it was included or excluded.
class KnownHeader {
llvm::PointerIntPair<Module *, 2, ModuleHeaderRole> Storage;
@@ -144,24 +160,24 @@ public:
return A.Storage != B.Storage;
}
- /// \brief Retrieve the module the header is stored in.
+ /// Retrieve the module the header is stored in.
Module *getModule() const { return Storage.getPointer(); }
- /// \brief The role of this header within the module.
+ /// The role of this header within the module.
ModuleHeaderRole getRole() const { return Storage.getInt(); }
- /// \brief Whether this header is available in the module.
+ /// Whether this header is available in the module.
bool isAvailable() const {
return getModule()->isAvailable();
}
- /// \brief Whether this header is accessible from the specified module.
+ /// Whether this header is accessible from the specified module.
bool isAccessibleFrom(Module *M) const {
return !(getRole() & PrivateHeader) ||
(M && M->getTopLevelModule() == getModule()->getTopLevelModule());
}
- // \brief Whether this known header is valid (i.e., it has an
+ // Whether this known header is valid (i.e., it has an
// associated module).
explicit operator bool() const {
return Storage.getPointer() != nullptr;
@@ -176,7 +192,7 @@ private:
using HeadersMap =
llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1>>;
- /// \brief Mapping from each header to the module that owns the contents of
+ /// Mapping from each header to the module that owns the contents of
/// that header.
HeadersMap Headers;
@@ -187,7 +203,7 @@ private:
mutable llvm::DenseMap<time_t, llvm::TinyPtrVector<Module*>>
LazyHeadersByModTime;
- /// \brief Mapping from directories with umbrella headers to the module
+ /// Mapping from directories with umbrella headers to the module
/// that is generated from the umbrella header.
///
/// This mapping is used to map headers that haven't explicitly been named
@@ -195,18 +211,27 @@ private:
/// header.
llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
- /// \brief The set of attributes that can be attached to a module.
+ /// A generation counter that is used to test whether modules of the
+ /// same name may shadow or are illegal redefinitions.
+ ///
+ /// Modules from earlier scopes may shadow modules from later ones.
+ /// Modules from the same scope may not have the same name.
+ unsigned CurrentModuleScopeID = 0;
+
+ llvm::DenseMap<Module *, unsigned> ModuleScopeIDs;
+
+ /// The set of attributes that can be attached to a module.
struct Attributes {
- /// \brief Whether this is a system module.
+ /// Whether this is a system module.
unsigned IsSystem : 1;
- /// \brief Whether this is an extern "C" module.
+ /// Whether this is an extern "C" module.
unsigned IsExternC : 1;
- /// \brief Whether this is an exhaustive set of configuration macros.
+ /// Whether this is an exhaustive set of configuration macros.
unsigned IsExhaustive : 1;
- /// \brief Whether files in this module can only include non-modular headers
+ /// Whether files in this module can only include non-modular headers
/// and headers from used modules.
unsigned NoUndeclaredIncludes : 1;
@@ -215,26 +240,26 @@ private:
NoUndeclaredIncludes(false) {}
};
- /// \brief A directory for which framework modules can be inferred.
+ /// A directory for which framework modules can be inferred.
struct InferredDirectory {
- /// \brief Whether to infer modules from this directory.
+ /// Whether to infer modules from this directory.
unsigned InferModules : 1;
- /// \brief The attributes to use for inferred modules.
+ /// The attributes to use for inferred modules.
Attributes Attrs;
- /// \brief If \c InferModules is non-zero, the module map file that allowed
+ /// If \c InferModules is non-zero, the module map file that allowed
/// inferred modules. Otherwise, nullptr.
const FileEntry *ModuleMapFile;
- /// \brief The names of modules that cannot be inferred within this
+ /// The names of modules that cannot be inferred within this
/// directory.
SmallVector<std::string, 2> ExcludedModules;
InferredDirectory() : InferModules(false) {}
};
- /// \brief A mapping from directories to information about inferring
+ /// A mapping from directories to information about inferring
/// framework modules from within those directories.
llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories;
@@ -244,11 +269,11 @@ private:
llvm::DenseMap<const Module *, AdditionalModMapsSet> AdditionalModMaps;
- /// \brief Describes whether we haved parsed a particular file as a module
+ /// Describes whether we haved parsed a particular file as a module
/// map.
llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap;
- /// \brief Resolve the given export declaration into an actual export
+ /// Resolve the given export declaration into an actual export
/// declaration.
///
/// \param Mod The module in which we're resolving the export declaration.
@@ -264,7 +289,7 @@ private:
resolveExport(Module *Mod, const Module::UnresolvedExportDecl &Unresolved,
bool Complain) const;
- /// \brief Resolve the given module id to an actual module.
+ /// Resolve the given module id to an actual module.
///
/// \param Id The module-id to resolve.
///
@@ -278,8 +303,15 @@ private:
Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const;
/// Add an unresolved header to a module.
+ ///
+ /// \param Mod The module in which we're adding the unresolved header
+ /// directive.
+ /// \param Header The unresolved header directive.
+ /// \param NeedsFramework If Mod is not a framework but a missing header would
+ /// be found in case Mod was, set it to true. False otherwise.
void addUnresolvedHeader(Module *Mod,
- Module::UnresolvedHeaderDirective Header);
+ Module::UnresolvedHeaderDirective Header,
+ bool &NeedsFramework);
/// Look up the given header directive to find an actual header file.
///
@@ -287,14 +319,22 @@ private:
/// \param Header The header directive to resolve.
/// \param RelativePathName Filled in with the relative path name from the
/// module to the resolved header.
+ /// \param NeedsFramework If M is not a framework but a missing header would
+ /// be found in case M was, set it to true. False otherwise.
/// \return The resolved file, if any.
const FileEntry *findHeader(Module *M,
const Module::UnresolvedHeaderDirective &Header,
- SmallVectorImpl<char> &RelativePathName);
+ SmallVectorImpl<char> &RelativePathName,
+ bool &NeedsFramework);
/// Resolve the given header directive.
- void resolveHeader(Module *M,
- const Module::UnresolvedHeaderDirective &Header);
+ ///
+ /// \param M The module in which we're resolving the header directive.
+ /// \param Header The header directive to resolve.
+ /// \param NeedsFramework If M is not a framework but a missing header would
+ /// be found in case M was, set it to true. False otherwise.
+ void resolveHeader(Module *M, const Module::UnresolvedHeaderDirective &Header,
+ bool &NeedsFramework);
/// Attempt to resolve the specified header directive as naming a builtin
/// header.
@@ -302,14 +342,14 @@ private:
bool resolveAsBuiltinHeader(Module *M,
const Module::UnresolvedHeaderDirective &Header);
- /// \brief Looks up the modules that \p File corresponds to.
+ /// Looks up the modules that \p File corresponds to.
///
/// If \p File represents a builtin header within Clang's builtin include
/// directory, this also loads all of the module maps to see if it will get
/// associated with a specific module (e.g. in /usr/include).
HeadersMap::iterator findKnownHeader(const FileEntry *File);
- /// \brief Searches for a module whose umbrella directory contains \p File.
+ /// Searches for a module whose umbrella directory contains \p File.
///
/// \param File The header to search for.
///
@@ -318,11 +358,11 @@ private:
KnownHeader findHeaderInUmbrellaDirs(const FileEntry *File,
SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs);
- /// \brief Given that \p File is not in the Headers map, look it up within
+ /// Given that \p File is not in the Headers map, look it up within
/// umbrella directories and find or create a module for it.
KnownHeader findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File);
- /// \brief A convenience method to determine if \p File is (possibly nested)
+ /// A convenience method to determine if \p File is (possibly nested)
/// in an umbrella directory.
bool isHeaderInUmbrellaDirs(const FileEntry *File) {
SmallVector<const DirectoryEntry *, 2> IntermediateDirs;
@@ -333,7 +373,7 @@ private:
Attributes Attrs, Module *Parent);
public:
- /// \brief Construct a new module map.
+ /// Construct a new module map.
///
/// \param SourceMgr The source manager used to find module files and headers.
/// This source manager should be shared with the header-search mechanism,
@@ -348,32 +388,32 @@ public:
const LangOptions &LangOpts, const TargetInfo *Target,
HeaderSearch &HeaderInfo);
- /// \brief Destroy the module map.
+ /// Destroy the module map.
~ModuleMap();
- /// \brief Set the target information.
+ /// Set the target information.
void setTarget(const TargetInfo &Target);
- /// \brief Set the directory that contains Clang-supplied include
+ /// Set the directory that contains Clang-supplied include
/// files, such as our stdarg.h or tgmath.h.
void setBuiltinIncludeDir(const DirectoryEntry *Dir) {
BuiltinIncludeDir = Dir;
}
- /// \brief Get the directory that contains Clang-supplied include files.
+ /// Get the directory that contains Clang-supplied include files.
const DirectoryEntry *getBuiltinDir() const {
return BuiltinIncludeDir;
}
- /// \brief Is this a compiler builtin header?
+ /// Is this a compiler builtin header?
static bool isBuiltinHeader(StringRef FileName);
- /// \brief Add a module map callback.
+ /// Add a module map callback.
void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) {
Callbacks.push_back(std::move(Callback));
}
- /// \brief Retrieve the module that owns the given header file, if any.
+ /// Retrieve the module that owns the given header file, if any.
///
/// \param File The header file that is likely to be included.
///
@@ -387,7 +427,7 @@ public:
KnownHeader findModuleForHeader(const FileEntry *File,
bool AllowTextual = false);
- /// \brief Retrieve all the modules that contain the given header file. This
+ /// Retrieve all the modules that contain the given header file. This
/// may not include umbrella modules, nor information from external sources,
/// if they have not yet been inferred / loaded.
///
@@ -404,7 +444,7 @@ public:
/// Resolve all lazy header directives for the specified module.
void resolveHeaderDirectives(Module *Mod) const;
- /// \brief Reports errors if a module must not include a specific file.
+ /// Reports errors if a module must not include a specific file.
///
/// \param RequestingModule The module including a file.
///
@@ -423,23 +463,23 @@ public:
SourceLocation FilenameLoc, StringRef Filename,
const FileEntry *File);
- /// \brief Determine whether the given header is part of a module
+ /// Determine whether the given header is part of a module
/// marked 'unavailable'.
bool isHeaderInUnavailableModule(const FileEntry *Header) const;
- /// \brief Determine whether the given header is unavailable as part
+ /// Determine whether the given header is unavailable as part
/// of the specified module.
bool isHeaderUnavailableInModule(const FileEntry *Header,
const Module *RequestingModule) const;
- /// \brief Retrieve a module with the given name.
+ /// Retrieve a module with the given name.
///
/// \param Name The name of the module to look up.
///
/// \returns The named module, if known; otherwise, returns null.
Module *findModule(StringRef Name) const;
- /// \brief Retrieve a module with the given name using lexical name lookup,
+ /// Retrieve a module with the given name using lexical name lookup,
/// starting at the given context.
///
/// \param Name The name of the module to look up.
@@ -450,7 +490,7 @@ public:
/// \returns The named module, if known; otherwise, returns null.
Module *lookupModuleUnqualified(StringRef Name, Module *Context) const;
- /// \brief Retrieve a module with the given name within the given context,
+ /// Retrieve a module with the given name within the given context,
/// using direct (qualified) name lookup.
///
/// \param Name The name of the module to look up.
@@ -461,7 +501,7 @@ public:
/// \returns The named submodule, if known; otherwose, returns null.
Module *lookupModuleQualified(StringRef Name, Module *Context) const;
- /// \brief Find a new module or submodule, or create it if it does not already
+ /// Find a new module or submodule, or create it if it does not already
/// exist.
///
/// \param Name The name of the module to find or create.
@@ -479,7 +519,7 @@ public:
bool IsFramework,
bool IsExplicit);
- /// \brief Create a 'global module' for a C++ Modules TS module interface
+ /// Create a 'global module' for a C++ Modules TS module interface
/// unit.
///
/// We model the global module as a submodule of the module interface unit.
@@ -487,7 +527,7 @@ public:
/// later, because we don't know what it will be called.
Module *createGlobalModuleForInterfaceUnit(SourceLocation Loc);
- /// \brief Create a new module for a C++ Modules TS module interface unit.
+ /// Create a new module for a C++ Modules TS module interface unit.
/// The module must not already exist, and will be configured for the current
/// compilation.
///
@@ -497,12 +537,30 @@ public:
Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name,
Module *GlobalModule);
- /// \brief Infer the contents of a framework module map from the given
+ /// Infer the contents of a framework module map from the given
/// framework directory.
Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir,
bool IsSystem, Module *Parent);
- /// \brief Retrieve the module map file containing the definition of the given
+ /// Create a new top-level module that is shadowed by
+ /// \p ShadowingModule.
+ Module *createShadowedModule(StringRef Name, bool IsFramework,
+ Module *ShadowingModule);
+
+ /// Creates a new declaration scope for module names, allowing
+ /// previously defined modules to shadow definitions from the new scope.
+ ///
+ /// \note Module names from earlier scopes will shadow names from the new
+ /// scope, which is the opposite of how shadowing works for variables.
+ void finishModuleDeclarationScope() { CurrentModuleScopeID += 1; }
+
+ bool mayShadowNewModule(Module *ExistingModule) {
+ assert(!ExistingModule->Parent && "expected top-level module");
+ assert(ModuleScopeIDs.count(ExistingModule) && "unknown module");
+ return ModuleScopeIDs[ExistingModule] < CurrentModuleScopeID;
+ }
+
+ /// Retrieve the module map file containing the definition of the given
/// module.
///
/// \param Module The module whose module map file will be returned, if known.
@@ -511,7 +569,7 @@ public:
/// module, or nullptr if the module definition was inferred.
const FileEntry *getContainingModuleMapFile(const Module *Module) const;
- /// \brief Get the module map file that (along with the module name) uniquely
+ /// Get the module map file that (along with the module name) uniquely
/// identifies this module.
///
/// The particular module that \c Name refers to may depend on how the module
@@ -524,7 +582,7 @@ public:
void setInferredModuleAllowedBy(Module *M, const FileEntry *ModuleMap);
- /// \brief Get any module map files other than getModuleMapFileForUniquing(M)
+ /// Get any module map files other than getModuleMapFileForUniquing(M)
/// that define submodules of a top-level module \p M. This is cheaper than
/// getting the module map file for each submodule individually, since the
/// expected number of results is very small.
@@ -539,7 +597,7 @@ public:
AdditionalModMaps[M].insert(ModuleMap);
}
- /// \brief Resolve all of the unresolved exports in the given module.
+ /// Resolve all of the unresolved exports in the given module.
///
/// \param Mod The module whose exports should be resolved.
///
@@ -549,7 +607,7 @@ public:
/// false otherwise.
bool resolveExports(Module *Mod, bool Complain);
- /// \brief Resolve all of the unresolved uses in the given module.
+ /// Resolve all of the unresolved uses in the given module.
///
/// \param Mod The module whose uses should be resolved.
///
@@ -559,7 +617,7 @@ public:
/// false otherwise.
bool resolveUses(Module *Mod, bool Complain);
- /// \brief Resolve all of the unresolved conflicts in the given module.
+ /// Resolve all of the unresolved conflicts in the given module.
///
/// \param Mod The module whose conflicts should be resolved.
///
@@ -569,25 +627,25 @@ public:
/// false otherwise.
bool resolveConflicts(Module *Mod, bool Complain);
- /// \brief Sets the umbrella header of the given module to the given
+ /// Sets the umbrella header of the given module to the given
/// header.
void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
Twine NameAsWritten);
- /// \brief Sets the umbrella directory of the given module to the given
+ /// Sets the umbrella directory of the given module to the given
/// directory.
void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
Twine NameAsWritten);
- /// \brief Adds this header to the given module.
+ /// Adds this header to the given module.
/// \param Role The role of the header wrt the module.
void addHeader(Module *Mod, Module::Header Header,
ModuleHeaderRole Role, bool Imported = false);
- /// \brief Marks this header as being excluded from the given module.
+ /// Marks this header as being excluded from the given module.
void excludeHeader(Module *Mod, Module::Header Header);
- /// \brief Parse the given module map file, and record any modules we
+ /// Parse the given module map file, and record any modules we
/// encounter.
///
/// \param File The file to be parsed.
@@ -608,11 +666,11 @@ public:
///
/// \returns true if an error occurred, false otherwise.
bool parseModuleMapFile(const FileEntry *File, bool IsSystem,
- const DirectoryEntry *HomeDir, FileID ID = FileID(),
- unsigned *Offset = nullptr,
+ const DirectoryEntry *HomeDir,
+ FileID ID = FileID(), unsigned *Offset = nullptr,
SourceLocation ExternModuleLoc = SourceLocation());
- /// \brief Dump the contents of the module map, for debugging purposes.
+ /// Dump the contents of the module map, for debugging purposes.
void dump();
using module_iterator = llvm::StringMap<Module *>::const_iterator;
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h
index 3967f8688966f..ac0dcc7b51c25 100644
--- a/include/clang/Lex/MultipleIncludeOpt.h
+++ b/include/clang/Lex/MultipleIncludeOpt.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the MultipleIncludeOpt interface.
+/// Defines the MultipleIncludeOpt interface.
//
//===----------------------------------------------------------------------===//
@@ -20,7 +20,7 @@
namespace clang {
class IdentifierInfo;
-/// \brief Implements the simple state machine that the Lexer class uses to
+/// Implements the simple state machine that the Lexer class uses to
/// detect files subject to the 'multiple-include' optimization.
///
/// The public methods in this class are triggered by various
@@ -113,13 +113,13 @@ public:
/// buffer, this method is called to disable the MIOpt if needed.
void ExpandedMacro() { DidMacroExpansion = true; }
- /// \brief Called when entering a top-level \#ifndef directive (or the
+ /// Called when entering a top-level \#ifndef directive (or the
/// "\#if !defined" equivalent) without any preceding tokens.
///
/// Note, we don't care about the input value of 'ReadAnyTokens'. The caller
/// ensures that this is only called if there are no tokens read before the
/// \#ifndef. The caller is required to do this, because reading the \#if
- /// line obviously reads in in tokens.
+ /// line obviously reads in tokens.
void EnterTopLevelIfndef(const IdentifierInfo *M, SourceLocation Loc) {
// If the macro is already set, this is after the top-level #endif.
if (TheMacro)
@@ -139,14 +139,14 @@ public:
MacroLoc = Loc;
}
- /// \brief Invoked when a top level conditional (except \#ifndef) is found.
+ /// Invoked when a top level conditional (except \#ifndef) is found.
void EnterTopLevelConditional() {
// If a conditional directive (except #ifndef) is found at the top level,
// there is a chunk of the file not guarded by the controlling macro.
Invalidate();
}
- /// \brief Called when the lexer exits the top-level conditional.
+ /// Called when the lexer exits the top-level conditional.
void ExitTopLevelConditional() {
// If we have a macro, that means the top of the file was ok. Set our state
// back to "not having read any tokens" so we can detect anything after the
@@ -159,7 +159,7 @@ public:
ImmediatelyAfterTopLevelIfndef = false;
}
- /// \brief Once the entire file has been lexed, if there is a controlling
+ /// Once the entire file has been lexed, if there is a controlling
/// macro, return it.
const IdentifierInfo *GetControllingMacroAtEndOfFile() const {
// If we haven't read any tokens after the #endif, return the controlling
@@ -169,7 +169,7 @@ public:
return nullptr;
}
- /// \brief If the ControllingMacro is followed by a macro definition, return
+ /// If the ControllingMacro is followed by a macro definition, return
/// the macro that was defined.
const IdentifierInfo *GetDefinedMacro() const {
return DefinedMacro;
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 19bce4dd32e88..eb85bda840afe 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Defines the PPCallbacks interface.
+/// Defines the PPCallbacks interface.
///
//===----------------------------------------------------------------------===//
@@ -29,7 +29,7 @@ namespace clang {
class MacroDirective;
class MacroArgs;
-/// \brief This interface provides a way to observe the actions of the
+/// This interface provides a way to observe the actions of the
/// preprocessor as it does its thing.
///
/// Clients can define their hooks here to implement preprocessor level tools.
@@ -41,7 +41,7 @@ public:
EnterFile, ExitFile, SystemHeaderPragma, RenameFile
};
- /// \brief Callback invoked whenever a source file is entered or exited.
+ /// Callback invoked whenever a source file is entered or exited.
///
/// \param Loc Indicates the new location.
/// \param PrevFID the file that was exited if \p Reason is ExitFile.
@@ -50,7 +50,7 @@ public:
FileID PrevFID = FileID()) {
}
- /// \brief Callback invoked whenever a source file is skipped as the result
+ /// Callback invoked whenever a source file is skipped as the result
/// of header guard optimization.
///
/// \param SkippedFile The file that is skipped instead of entering \#include
@@ -63,7 +63,7 @@ public:
SrcMgr::CharacteristicKind FileType) {
}
- /// \brief Callback invoked whenever an inclusion directive results in a
+ /// Callback invoked whenever an inclusion directive results in a
/// file-not-found error.
///
/// \param FileName The name of the file being included, as written in the
@@ -80,7 +80,7 @@ public:
return false;
}
- /// \brief Callback invoked whenever an inclusion directive of
+ /// Callback invoked whenever an inclusion directive of
/// any kind (\c \#include, \c \#import, etc.) has been processed, regardless
/// of whether the inclusion will actually result in an inclusion.
///
@@ -117,6 +117,10 @@ public:
/// \param Imported The module, whenever an inclusion directive was
/// automatically turned into a module import or null otherwise.
///
+ /// \param FileType The characteristic kind, indicates whether a file or
+ /// directory holds normal user code, system code, or system code which is
+ /// implicitly 'extern "C"' in C++ mode.
+ ///
virtual void InclusionDirective(SourceLocation HashLoc,
const Token &IncludeTok,
StringRef FileName,
@@ -125,10 +129,11 @@ public:
const FileEntry *File,
StringRef SearchPath,
StringRef RelativePath,
- const Module *Imported) {
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) {
}
- /// \brief Callback invoked whenever there was an explicit module-import
+ /// Callback invoked whenever there was an explicit module-import
/// syntax.
///
/// \param ImportLoc The location of import directive token.
@@ -143,54 +148,54 @@ public:
const Module *Imported) {
}
- /// \brief Callback invoked when the end of the main file is reached.
+ /// Callback invoked when the end of the main file is reached.
///
/// No subsequent callbacks will be made.
virtual void EndOfMainFile() {
}
- /// \brief Callback invoked when a \#ident or \#sccs directive is read.
+ /// Callback invoked when a \#ident or \#sccs directive is read.
/// \param Loc The location of the directive.
/// \param str The text of the directive.
///
virtual void Ident(SourceLocation Loc, StringRef str) {
}
- /// \brief Callback invoked when start reading any pragma directive.
+ /// Callback invoked when start reading any pragma directive.
virtual void PragmaDirective(SourceLocation Loc,
PragmaIntroducerKind Introducer) {
}
- /// \brief Callback invoked when a \#pragma comment directive is read.
+ /// Callback invoked when a \#pragma comment directive is read.
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
StringRef Str) {
}
- /// \brief Callback invoked when a \#pragma detect_mismatch directive is
+ /// Callback invoked when a \#pragma detect_mismatch directive is
/// read.
virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
StringRef Value) {
}
- /// \brief Callback invoked when a \#pragma clang __debug directive is read.
+ /// Callback invoked when a \#pragma clang __debug directive is read.
/// \param Loc The location of the debug directive.
/// \param DebugType The identifier following __debug.
virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) {
}
- /// \brief Determines the kind of \#pragma invoking a call to PragmaMessage.
+ /// Determines the kind of \#pragma invoking a call to PragmaMessage.
enum PragmaMessageKind {
- /// \brief \#pragma message has been invoked.
+ /// \#pragma message has been invoked.
PMK_Message,
- /// \brief \#pragma GCC warning has been invoked.
+ /// \#pragma GCC warning has been invoked.
PMK_Warning,
- /// \brief \#pragma GCC error has been invoked.
+ /// \#pragma GCC error has been invoked.
PMK_Error
};
- /// \brief Callback invoked when a \#pragma message directive is read.
+ /// Callback invoked when a \#pragma message directive is read.
/// \param Loc The location of the message directive.
/// \param Namespace The namespace of the message directive.
/// \param Kind The type of the message directive.
@@ -199,62 +204,62 @@ public:
PragmaMessageKind Kind, StringRef Str) {
}
- /// \brief Callback invoked when a \#pragma gcc diagnostic push directive
+ /// Callback invoked when a \#pragma gcc diagnostic push directive
/// is read.
virtual void PragmaDiagnosticPush(SourceLocation Loc,
StringRef Namespace) {
}
- /// \brief Callback invoked when a \#pragma gcc diagnostic pop directive
+ /// Callback invoked when a \#pragma gcc diagnostic pop directive
/// is read.
virtual void PragmaDiagnosticPop(SourceLocation Loc,
StringRef Namespace) {
}
- /// \brief Callback invoked when a \#pragma gcc diagnostic directive is read.
+ /// Callback invoked when a \#pragma gcc diagnostic directive is read.
virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
diag::Severity mapping, StringRef Str) {}
- /// \brief Called when an OpenCL extension is either disabled or
+ /// Called when an OpenCL extension is either disabled or
/// enabled with a pragma.
virtual void PragmaOpenCLExtension(SourceLocation NameLoc,
const IdentifierInfo *Name,
SourceLocation StateLoc, unsigned State) {
}
- /// \brief Callback invoked when a \#pragma warning directive is read.
+ /// Callback invoked when a \#pragma warning directive is read.
virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
ArrayRef<int> Ids) {
}
- /// \brief Callback invoked when a \#pragma warning(push) directive is read.
+ /// Callback invoked when a \#pragma warning(push) directive is read.
virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
}
- /// \brief Callback invoked when a \#pragma warning(pop) directive is read.
+ /// Callback invoked when a \#pragma warning(pop) directive is read.
virtual void PragmaWarningPop(SourceLocation Loc) {
}
- /// \brief Callback invoked when a \#pragma clang assume_nonnull begin directive
+ /// Callback invoked when a \#pragma clang assume_nonnull begin directive
/// is read.
virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {}
- /// \brief Callback invoked when a \#pragma clang assume_nonnull end directive
+ /// Callback invoked when a \#pragma clang assume_nonnull end directive
/// is read.
virtual void PragmaAssumeNonNullEnd(SourceLocation Loc) {}
- /// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a
+ /// Called by Preprocessor::HandleMacroExpandedIdentifier when a
/// macro invocation is found.
virtual void MacroExpands(const Token &MacroNameTok,
const MacroDefinition &MD, SourceRange Range,
const MacroArgs *Args) {}
- /// \brief Hook called whenever a macro definition is seen.
+ /// Hook called whenever a macro definition is seen.
virtual void MacroDefined(const Token &MacroNameTok,
const MacroDirective *MD) {
}
- /// \brief Hook called whenever a macro \#undef is seen.
+ /// Hook called whenever a macro \#undef is seen.
/// \param MacroNameTok The active Token
/// \param MD A MacroDefinition for the named macro.
/// \param Undef New MacroDirective if the macro was defined, null otherwise.
@@ -265,13 +270,13 @@ public:
const MacroDirective *Undef) {
}
- /// \brief Hook called whenever the 'defined' operator is seen.
+ /// Hook called whenever the 'defined' operator is seen.
/// \param MD The MacroDirective if the name was a macro, null otherwise.
virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range) {
}
- /// \brief Hook called when a source range is skipped.
+ /// Hook called when a source range is skipped.
/// \param Range The SourceRange that was skipped. The range begins at the
/// \#if/\#else directive and ends after the \#endif/\#else directive.
/// \param EndifLoc The end location of the 'endif' token, which may precede
@@ -284,7 +289,7 @@ public:
CVK_NotEvaluated, CVK_False, CVK_True
};
- /// \brief Hook called whenever an \#if is seen.
+ /// Hook called whenever an \#if is seen.
/// \param Loc the source location of the directive.
/// \param ConditionRange The SourceRange of the expression being tested.
/// \param ConditionValue The evaluated value of the condition.
@@ -294,7 +299,7 @@ public:
ConditionValueKind ConditionValue) {
}
- /// \brief Hook called whenever an \#elif is seen.
+ /// Hook called whenever an \#elif is seen.
/// \param Loc the source location of the directive.
/// \param ConditionRange The SourceRange of the expression being tested.
/// \param ConditionValue The evaluated value of the condition.
@@ -304,7 +309,7 @@ public:
ConditionValueKind ConditionValue, SourceLocation IfLoc) {
}
- /// \brief Hook called whenever an \#ifdef is seen.
+ /// Hook called whenever an \#ifdef is seen.
/// \param Loc the source location of the directive.
/// \param MacroNameTok Information on the token being tested.
/// \param MD The MacroDefinition if the name was a macro, null otherwise.
@@ -312,7 +317,7 @@ public:
const MacroDefinition &MD) {
}
- /// \brief Hook called whenever an \#ifndef is seen.
+ /// Hook called whenever an \#ifndef is seen.
/// \param Loc the source location of the directive.
/// \param MacroNameTok Information on the token being tested.
/// \param MD The MacroDefiniton if the name was a macro, null otherwise.
@@ -320,20 +325,20 @@ public:
const MacroDefinition &MD) {
}
- /// \brief Hook called whenever an \#else is seen.
+ /// Hook called whenever an \#else is seen.
/// \param Loc the source location of the directive.
/// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
}
- /// \brief Hook called whenever an \#endif is seen.
+ /// Hook called whenever an \#endif is seen.
/// \param Loc the source location of the directive.
/// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
}
};
-/// \brief Simple wrapper class for chaining callbacks.
+/// Simple wrapper class for chaining callbacks.
class PPChainedCallbacks : public PPCallbacks {
virtual void anchor();
std::unique_ptr<PPCallbacks> First, Second;
@@ -367,13 +372,14 @@ public:
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath,
- const Module *Imported) override {
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) override {
First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
FilenameRange, File, SearchPath, RelativePath,
- Imported);
+ Imported, FileType);
Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
FilenameRange, File, SearchPath, RelativePath,
- Imported);
+ Imported, FileType);
}
void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
@@ -499,41 +505,41 @@ public:
Second->SourceRangeSkipped(Range, EndifLoc);
}
- /// \brief Hook called whenever an \#if is seen.
+ /// Hook called whenever an \#if is seen.
void If(SourceLocation Loc, SourceRange ConditionRange,
ConditionValueKind ConditionValue) override {
First->If(Loc, ConditionRange, ConditionValue);
Second->If(Loc, ConditionRange, ConditionValue);
}
- /// \brief Hook called whenever an \#elif is seen.
+ /// Hook called whenever an \#elif is seen.
void Elif(SourceLocation Loc, SourceRange ConditionRange,
ConditionValueKind ConditionValue, SourceLocation IfLoc) override {
First->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
}
- /// \brief Hook called whenever an \#ifdef is seen.
+ /// Hook called whenever an \#ifdef is seen.
void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDefinition &MD) override {
First->Ifdef(Loc, MacroNameTok, MD);
Second->Ifdef(Loc, MacroNameTok, MD);
}
- /// \brief Hook called whenever an \#ifndef is seen.
+ /// Hook called whenever an \#ifndef is seen.
void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDefinition &MD) override {
First->Ifndef(Loc, MacroNameTok, MD);
Second->Ifndef(Loc, MacroNameTok, MD);
}
- /// \brief Hook called whenever an \#else is seen.
+ /// Hook called whenever an \#else is seen.
void Else(SourceLocation Loc, SourceLocation IfLoc) override {
First->Else(Loc, IfLoc);
Second->Else(Loc, IfLoc);
}
- /// \brief Hook called whenever an \#endif is seen.
+ /// Hook called whenever an \#endif is seen.
void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
First->Endif(Loc, IfLoc);
Second->Endif(Loc, IfLoc);
diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h
index 8c5227561b838..a653b8339948d 100644
--- a/include/clang/Lex/PPConditionalDirectiveRecord.h
+++ b/include/clang/Lex/PPConditionalDirectiveRecord.h
@@ -21,7 +21,7 @@
namespace clang {
-/// \brief Records preprocessor conditional directive regions and allows
+/// Records preprocessor conditional directive regions and allows
/// querying in which region source locations belong to.
class PPConditionalDirectiveRecord : public PPCallbacks {
SourceManager &SourceMgr;
@@ -57,25 +57,25 @@ class PPConditionalDirectiveRecord : public PPCallbacks {
};
typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
- /// \brief The locations of conditional directives in source order.
+ /// The locations of conditional directives in source order.
CondDirectiveLocsTy CondDirectiveLocs;
void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
public:
- /// \brief Construct a new preprocessing record.
+ /// Construct a new preprocessing record.
explicit PPConditionalDirectiveRecord(SourceManager &SM);
size_t getTotalMemory() const;
SourceManager &getSourceManager() const { return SourceMgr; }
- /// \brief Returns true if the given range intersects with a conditional
+ /// Returns true if the given range intersects with a conditional
/// directive. if a \#if/\#endif block is fully contained within the range,
/// this function will return false.
bool rangeIntersectsConditionalDirective(SourceRange Range) const;
- /// \brief Returns true if the given locations are in different regions,
+ /// Returns true if the given locations are in different regions,
/// separated by conditional directive blocks.
bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS,
SourceLocation RHS) const {
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index 090ae2a98236e..9348388bc28cf 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -26,22 +26,22 @@ class Preprocessor;
class Token;
/**
- * \brief Describes how the pragma was introduced, e.g., with \#pragma,
+ * Describes how the pragma was introduced, e.g., with \#pragma,
* _Pragma, or __pragma.
*/
enum PragmaIntroducerKind {
/**
- * \brief The pragma was introduced via \#pragma.
+ * The pragma was introduced via \#pragma.
*/
PIK_HashPragma,
/**
- * \brief The pragma was introduced via the C99 _Pragma(string-literal).
+ * The pragma was introduced via the C99 _Pragma(string-literal).
*/
PIK__Pragma,
/**
- * \brief The pragma was introduced via the Microsoft
+ * The pragma was introduced via the Microsoft
* __pragma(token-string).
*/
PIK___pragma
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 5f7a6efcef107..54e28a52f5b36 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -39,11 +39,11 @@ class PreprocessingRecord;
} // namespace clang
-/// \brief Allocates memory within a Clang preprocessing record.
+/// Allocates memory within a Clang preprocessing record.
void *operator new(size_t bytes, clang::PreprocessingRecord &PR,
unsigned alignment = 8) noexcept;
-/// \brief Frees memory allocated in a Clang preprocessing record.
+/// Frees memory allocated in a Clang preprocessing record.
void operator delete(void *ptr, clang::PreprocessingRecord &PR,
unsigned) noexcept;
@@ -55,25 +55,25 @@ class MacroInfo;
class SourceManager;
class Token;
- /// \brief Base class that describes a preprocessed entity, which may be a
+ /// Base class that describes a preprocessed entity, which may be a
/// preprocessor directive or macro expansion.
class PreprocessedEntity {
public:
- /// \brief The kind of preprocessed entity an object describes.
+ /// The kind of preprocessed entity an object describes.
enum EntityKind {
- /// \brief Indicates a problem trying to load the preprocessed entity.
+ /// Indicates a problem trying to load the preprocessed entity.
InvalidKind,
- /// \brief A macro expansion.
+ /// A macro expansion.
MacroExpansionKind,
/// \defgroup Preprocessing directives
/// @{
- /// \brief A macro definition.
+ /// A macro definition.
MacroDefinitionKind,
- /// \brief An inclusion directive, such as \c \#include, \c
+ /// An inclusion directive, such as \c \#include, \c
/// \#import, or \c \#include_next.
InclusionDirectiveKind,
@@ -84,10 +84,10 @@ class Token;
};
private:
- /// \brief The kind of preprocessed entity that this object describes.
+ /// The kind of preprocessed entity that this object describes.
EntityKind Kind;
- /// \brief The source range that covers this preprocessed entity.
+ /// The source range that covers this preprocessed entity.
SourceRange Range;
protected:
@@ -97,14 +97,14 @@ class Token;
: Kind(Kind), Range(Range) {}
public:
- /// \brief Retrieve the kind of preprocessed entity stored in this object.
+ /// Retrieve the kind of preprocessed entity stored in this object.
EntityKind getKind() const { return Kind; }
- /// \brief Retrieve the source range that covers this entire preprocessed
+ /// Retrieve the source range that covers this entire preprocessed
/// entity.
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- /// \brief Returns true if there was a problem loading the preprocessed
+ /// Returns true if there was a problem loading the preprocessed
/// entity.
bool isInvalid() const { return Kind == InvalidKind; }
@@ -131,7 +131,7 @@ class Token;
void operator delete(void *data) noexcept;
};
- /// \brief Records the presence of a preprocessor directive.
+ /// Records the presence of a preprocessor directive.
class PreprocessingDirective : public PreprocessedEntity {
public:
PreprocessingDirective(EntityKind Kind, SourceRange Range)
@@ -144,9 +144,9 @@ class Token;
}
};
- /// \brief Record the location of a macro definition.
+ /// Record the location of a macro definition.
class MacroDefinitionRecord : public PreprocessingDirective {
- /// \brief The name of the macro being defined.
+ /// The name of the macro being defined.
const IdentifierInfo *Name;
public:
@@ -154,10 +154,10 @@ class Token;
SourceRange Range)
: PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) {}
- /// \brief Retrieve the name of the macro being defined.
+ /// Retrieve the name of the macro being defined.
const IdentifierInfo *getName() const { return Name; }
- /// \brief Retrieve the location of the macro name in the definition.
+ /// Retrieve the location of the macro name in the definition.
SourceLocation getLocation() const { return getSourceRange().getBegin(); }
// Implement isa/cast/dyncast/etc.
@@ -166,9 +166,9 @@ class Token;
}
};
- /// \brief Records the location of a macro expansion.
+ /// Records the location of a macro expansion.
class MacroExpansion : public PreprocessedEntity {
- /// \brief The definition of this macro or the name of the macro if it is
+ /// The definition of this macro or the name of the macro if it is
/// a builtin macro.
llvm::PointerUnion<IdentifierInfo *, MacroDefinitionRecord *> NameOrDef;
@@ -181,17 +181,17 @@ class Token;
: PreprocessedEntity(MacroExpansionKind, Range), NameOrDef(Definition) {
}
- /// \brief True if it is a builtin macro.
+ /// True if it is a builtin macro.
bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); }
- /// \brief The name of the macro being expanded.
+ /// The name of the macro being expanded.
const IdentifierInfo *getName() const {
if (MacroDefinitionRecord *Def = getDefinition())
return Def->getName();
return NameOrDef.get<IdentifierInfo *>();
}
- /// \brief The definition of the macro being expanded. May return null if
+ /// The definition of the macro being expanded. May return null if
/// this is a builtin macro.
MacroDefinitionRecord *getDefinition() const {
return NameOrDef.dyn_cast<MacroDefinitionRecord *>();
@@ -203,45 +203,45 @@ class Token;
}
};
- /// \brief Record the location of an inclusion directive, such as an
+ /// Record the location of an inclusion directive, such as an
/// \c \#include or \c \#import statement.
class InclusionDirective : public PreprocessingDirective {
public:
- /// \brief The kind of inclusion directives known to the
+ /// The kind of inclusion directives known to the
/// preprocessor.
enum InclusionKind {
- /// \brief An \c \#include directive.
+ /// An \c \#include directive.
Include,
- /// \brief An Objective-C \c \#import directive.
+ /// An Objective-C \c \#import directive.
Import,
- /// \brief A GNU \c \#include_next directive.
+ /// A GNU \c \#include_next directive.
IncludeNext,
- /// \brief A Clang \c \#__include_macros directive.
+ /// A Clang \c \#__include_macros directive.
IncludeMacros
};
private:
- /// \brief The name of the file that was included, as written in
+ /// The name of the file that was included, as written in
/// the source.
StringRef FileName;
- /// \brief Whether the file name was in quotation marks; otherwise, it was
+ /// Whether the file name was in quotation marks; otherwise, it was
/// in angle brackets.
unsigned InQuotes : 1;
- /// \brief The kind of inclusion directive we have.
+ /// The kind of inclusion directive we have.
///
/// This is a value of type InclusionKind.
unsigned Kind : 2;
- /// \brief Whether the inclusion directive was automatically turned into
+ /// Whether the inclusion directive was automatically turned into
/// a module import.
unsigned ImportedModule : 1;
- /// \brief The file that was included.
+ /// The file that was included.
const FileEntry *File;
public:
@@ -250,21 +250,21 @@ class Token;
bool InQuotes, bool ImportedModule,
const FileEntry *File, SourceRange Range);
- /// \brief Determine what kind of inclusion directive this is.
+ /// Determine what kind of inclusion directive this is.
InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); }
- /// \brief Retrieve the included file name as it was written in the source.
+ /// Retrieve the included file name as it was written in the source.
StringRef getFileName() const { return FileName; }
- /// \brief Determine whether the included file name was written in quotes;
+ /// Determine whether the included file name was written in quotes;
/// otherwise, it was written in angle brackets.
bool wasInQuotes() const { return InQuotes; }
- /// \brief Determine whether the inclusion directive was automatically
+ /// Determine whether the inclusion directive was automatically
/// turned into a module import.
bool importedModule() const { return ImportedModule; }
- /// \brief Retrieve the file entry for the actual file that was included
+ /// Retrieve the file entry for the actual file that was included
/// by this directive.
const FileEntry *getFile() const { return File; }
@@ -274,55 +274,60 @@ class Token;
}
};
- /// \brief An abstract class that should be subclassed by any external source
+ /// An abstract class that should be subclassed by any external source
/// of preprocessing record entries.
class ExternalPreprocessingRecordSource {
public:
virtual ~ExternalPreprocessingRecordSource();
- /// \brief Read a preallocated preprocessed entity from the external source.
+ /// Read a preallocated preprocessed entity from the external source.
///
/// \returns null if an error occurred that prevented the preprocessed
/// entity from being loaded.
virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) = 0;
- /// \brief Returns a pair of [Begin, End) indices of preallocated
+ /// Returns a pair of [Begin, End) indices of preallocated
/// preprocessed entities that \p Range encompasses.
virtual std::pair<unsigned, unsigned>
findPreprocessedEntitiesInRange(SourceRange Range) = 0;
- /// \brief Optionally returns true or false if the preallocated preprocessed
+ /// Optionally returns true or false if the preallocated preprocessed
/// entity with index \p Index came from file \p FID.
virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
FileID FID) {
return None;
}
+
+ /// Read a preallocated skipped range from the external source.
+ virtual SourceRange ReadSkippedRange(unsigned Index) = 0;
};
- /// \brief A record of the steps taken while preprocessing a source file,
+ /// A record of the steps taken while preprocessing a source file,
/// including the various preprocessing directives processed, macros
/// expanded, etc.
class PreprocessingRecord : public PPCallbacks {
SourceManager &SourceMgr;
- /// \brief Allocator used to store preprocessing objects.
+ /// Allocator used to store preprocessing objects.
llvm::BumpPtrAllocator BumpAlloc;
- /// \brief The set of preprocessed entities in this record, in order they
+ /// The set of preprocessed entities in this record, in order they
/// were seen.
std::vector<PreprocessedEntity *> PreprocessedEntities;
- /// \brief The set of preprocessed entities in this record that have been
+ /// The set of preprocessed entities in this record that have been
/// loaded from external sources.
///
/// The entries in this vector are loaded lazily from the external source,
/// and are referenced by the iterator using negative indices.
std::vector<PreprocessedEntity *> LoadedPreprocessedEntities;
- /// \brief The set of ranges that were skipped by the preprocessor,
+ /// The set of ranges that were skipped by the preprocessor,
std::vector<SourceRange> SkippedRanges;
- /// \brief Global (loaded or local) ID for a preprocessed entity.
+ bool SkippedRangesAllLoaded = true;
+
+ /// Global (loaded or local) ID for a preprocessed entity.
/// Negative values are used to indicate preprocessed entities
/// loaded from the external source while non-negative values are used to
/// indicate preprocessed entities introduced by the current preprocessor.
@@ -346,50 +351,60 @@ class Token;
return isLoaded ? PPEntityID(-int(Index)-1) : PPEntityID(Index+1);
}
- /// \brief Mapping from MacroInfo structures to their definitions.
+ /// Mapping from MacroInfo structures to their definitions.
llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *> MacroDefinitions;
- /// \brief External source of preprocessed entities.
+ /// External source of preprocessed entities.
ExternalPreprocessingRecordSource *ExternalSource = nullptr;
- /// \brief Retrieve the preprocessed entity at the given ID.
+ /// Retrieve the preprocessed entity at the given ID.
PreprocessedEntity *getPreprocessedEntity(PPEntityID PPID);
- /// \brief Retrieve the loaded preprocessed entity at the given index.
+ /// Retrieve the loaded preprocessed entity at the given index.
PreprocessedEntity *getLoadedPreprocessedEntity(unsigned Index);
- /// \brief Determine the number of preprocessed entities that were
+ /// Determine the number of preprocessed entities that were
/// loaded (or can be loaded) from an external source.
unsigned getNumLoadedPreprocessedEntities() const {
return LoadedPreprocessedEntities.size();
}
- /// \brief Returns a pair of [Begin, End) indices of local preprocessed
+ /// Returns a pair of [Begin, End) indices of local preprocessed
/// entities that \p Range encompasses.
std::pair<unsigned, unsigned>
findLocalPreprocessedEntitiesInRange(SourceRange Range) const;
unsigned findBeginLocalPreprocessedEntity(SourceLocation Loc) const;
unsigned findEndLocalPreprocessedEntity(SourceLocation Loc) const;
- /// \brief Allocate space for a new set of loaded preprocessed entities.
+ /// Allocate space for a new set of loaded preprocessed entities.
///
/// \returns The index into the set of loaded preprocessed entities, which
/// corresponds to the first newly-allocated entity.
unsigned allocateLoadedEntities(unsigned NumEntities);
- /// \brief Register a new macro definition.
+ /// Allocate space for a new set of loaded preprocessed skipped
+ /// ranges.
+ ///
+ /// \returns The index into the set of loaded preprocessed ranges, which
+ /// corresponds to the first newly-allocated range.
+ unsigned allocateSkippedRanges(unsigned NumRanges);
+
+ /// Ensures that all external skipped ranges have been loaded.
+ void ensureSkippedRangesLoaded();
+
+ /// Register a new macro definition.
void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinitionRecord *Def);
public:
- /// \brief Construct a new preprocessing record.
+ /// Construct a new preprocessing record.
explicit PreprocessingRecord(SourceManager &SM);
- /// \brief Allocate memory in the preprocessing record.
+ /// Allocate memory in the preprocessing record.
void *Allocate(unsigned Size, unsigned Align = 8) {
return BumpAlloc.Allocate(Size, Align);
}
- /// \brief Deallocate memory in the preprocessing record.
+ /// Deallocate memory in the preprocessing record.
void Deallocate(void *Ptr) {}
size_t getTotalMemory() const;
@@ -436,27 +451,27 @@ class Token;
PreprocessedEntity *operator->() const { return **this; }
};
- /// \brief Begin iterator for all preprocessed entities.
+ /// Begin iterator for all preprocessed entities.
iterator begin() {
return iterator(this, -(int)LoadedPreprocessedEntities.size());
}
- /// \brief End iterator for all preprocessed entities.
+ /// End iterator for all preprocessed entities.
iterator end() {
return iterator(this, PreprocessedEntities.size());
}
- /// \brief Begin iterator for local, non-loaded, preprocessed entities.
+ /// Begin iterator for local, non-loaded, preprocessed entities.
iterator local_begin() {
return iterator(this, 0);
}
- /// \brief End iterator for local, non-loaded, preprocessed entities.
+ /// End iterator for local, non-loaded, preprocessed entities.
iterator local_end() {
return iterator(this, PreprocessedEntities.size());
}
- /// \brief iterator range for the given range of loaded
+ /// iterator range for the given range of loaded
/// preprocessed entities.
llvm::iterator_range<iterator> getIteratorsForLoadedRange(unsigned start,
unsigned count) {
@@ -467,14 +482,14 @@ class Token;
iterator(this, int(end) - LoadedPreprocessedEntities.size()));
}
- /// \brief Returns a range of preprocessed entities that source range \p R
+ /// Returns a range of preprocessed entities that source range \p R
/// encompasses.
///
/// \param R the range to look for preprocessed entities.
llvm::iterator_range<iterator>
getPreprocessedEntitiesInRange(SourceRange R);
- /// \brief Returns true if the preprocessed entity that \p PPEI iterator
+ /// Returns true if the preprocessed entity that \p PPEI iterator
/// points to is coming from the file \p FID.
///
/// Can be used to avoid implicit deserializations of preallocated
@@ -483,23 +498,24 @@ class Token;
/// \see getPreprocessedEntitiesInRange.
bool isEntityInFileID(iterator PPEI, FileID FID);
- /// \brief Add a new preprocessed entity to this record.
+ /// Add a new preprocessed entity to this record.
PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity);
- /// \brief Set the external source for preprocessed entities.
+ /// Set the external source for preprocessed entities.
void SetExternalSource(ExternalPreprocessingRecordSource &Source);
- /// \brief Retrieve the external source for preprocessed entities.
+ /// Retrieve the external source for preprocessed entities.
ExternalPreprocessingRecordSource *getExternalSource() const {
return ExternalSource;
}
- /// \brief Retrieve the macro definition that corresponds to the given
+ /// Retrieve the macro definition that corresponds to the given
/// \c MacroInfo.
MacroDefinitionRecord *findMacroDefinition(const MacroInfo *MI);
- /// \brief Retrieve all ranges that got skipped while preprocessing.
- const std::vector<SourceRange> &getSkippedRanges() const {
+ /// Retrieve all ranges that got skipped while preprocessing.
+ const std::vector<SourceRange> &getSkippedRanges() {
+ ensureSkippedRangesLoaded();
return SkippedRanges;
}
@@ -516,14 +532,14 @@ class Token;
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange,
const FileEntry *File, StringRef SearchPath,
- StringRef RelativePath,
- const Module *Imported) override;
+ StringRef RelativePath, const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) override;
void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDefinition &MD) override;
void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDefinition &MD) override;
- /// \brief Hook called whenever the 'defined' operator is seen.
+ /// Hook called whenever the 'defined' operator is seen.
void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range) override;
@@ -533,7 +549,7 @@ class Token;
void addMacroExpansion(const Token &Id, const MacroInfo *MI,
SourceRange Range);
- /// \brief Cached result of the last \see getPreprocessedEntitiesInRange
+ /// Cached result of the last \see getPreprocessedEntitiesInRange
/// query.
struct {
SourceRange Range;
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 485600f122329..4ec29fe8f331c 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Defines the clang::Preprocessor interface.
+/// Defines the clang::Preprocessor interface.
//
//===----------------------------------------------------------------------===//
@@ -83,7 +83,7 @@ class PTHManager;
class ScratchBuffer;
class TargetInfo;
-/// \brief Stores token information for comparing actual tokens with
+/// Stores token information for comparing actual tokens with
/// predefined values. Only handles simple tokens and identifiers.
class TokenValue {
tok::TokenKind Kind;
@@ -106,7 +106,7 @@ public:
}
};
-/// \brief Context in which macro name is used.
+/// Context in which macro name is used.
enum MacroUse {
// other than #define or #undef
MU_Other = 0,
@@ -118,7 +118,7 @@ enum MacroUse {
MU_Undef = 2
};
-/// \brief Engages in a tight little dance with the lexer to efficiently
+/// Engages in a tight little dance with the lexer to efficiently
/// preprocess tokens.
///
/// Lexers know only about tokens within a single source file, and don't
@@ -140,7 +140,7 @@ class Preprocessor {
HeaderSearch &HeaderInfo;
ModuleLoader &TheModuleLoader;
- /// \brief External source of macros.
+ /// External source of macros.
ExternalPreprocessorSource *ExternalSource;
/// An optional PTHManager object used for getting tokens from
@@ -186,7 +186,7 @@ class Preprocessor {
unsigned CounterValue = 0;
enum {
- /// \brief Maximum depth of \#includes.
+ /// Maximum depth of \#includes.
MaxAllowedIncludeStackDepth = 200
};
@@ -210,26 +210,26 @@ class Preprocessor {
class ResetMacroExpansionHelper;
- /// \brief Whether we have already loaded macros from the external source.
+ /// Whether we have already loaded macros from the external source.
mutable bool ReadMacrosFromExternalSource : 1;
- /// \brief True if pragmas are enabled.
+ /// True if pragmas are enabled.
bool PragmasEnabled : 1;
- /// \brief True if the current build action is a preprocessing action.
+ /// True if the current build action is a preprocessing action.
bool PreprocessedOutput : 1;
- /// \brief True if we are currently preprocessing a #if or #elif directive
+ /// True if we are currently preprocessing a #if or #elif directive
bool ParsingIfOrElifDirective;
- /// \brief True if we are pre-expanding macro arguments.
+ /// True if we are pre-expanding macro arguments.
bool InMacroArgPreExpansion;
- /// \brief Mapping/lookup information for all identifiers in
+ /// Mapping/lookup information for all identifiers in
/// the program, including program keywords.
mutable IdentifierTable Identifiers;
- /// \brief This table contains all the selectors in the program.
+ /// This table contains all the selectors in the program.
///
/// Unlike IdentifierTable above, this table *isn't* populated by the
/// preprocessor. It is declared/expanded here because its role/lifetime is
@@ -240,82 +240,82 @@ class Preprocessor {
/// the lifetime of the preprocessor.
SelectorTable Selectors;
- /// \brief Information about builtins.
+ /// Information about builtins.
Builtin::Context BuiltinInfo;
- /// \brief Tracks all of the pragmas that the client registered
+ /// Tracks all of the pragmas that the client registered
/// with this preprocessor.
std::unique_ptr<PragmaNamespace> PragmaHandlers;
- /// \brief Pragma handlers of the original source is stored here during the
+ /// Pragma handlers of the original source is stored here during the
/// parsing of a model file.
std::unique_ptr<PragmaNamespace> PragmaHandlersBackup;
- /// \brief Tracks all of the comment handlers that the client registered
+ /// Tracks all of the comment handlers that the client registered
/// with this preprocessor.
std::vector<CommentHandler *> CommentHandlers;
- /// \brief True if we want to ignore EOF token and continue later on (thus
+ /// True if we want to ignore EOF token and continue later on (thus
/// avoid tearing the Lexer and etc. down).
bool IncrementalProcessing = false;
/// The kind of translation unit we are processing.
TranslationUnitKind TUKind;
- /// \brief The code-completion handler.
+ /// The code-completion handler.
CodeCompletionHandler *CodeComplete = nullptr;
- /// \brief The file that we're performing code-completion for, if any.
+ /// The file that we're performing code-completion for, if any.
const FileEntry *CodeCompletionFile = nullptr;
- /// \brief The offset in file for the code-completion point.
+ /// The offset in file for the code-completion point.
unsigned CodeCompletionOffset = 0;
- /// \brief The location for the code-completion point. This gets instantiated
+ /// The location for the code-completion point. This gets instantiated
/// when the CodeCompletionFile gets \#include'ed for preprocessing.
SourceLocation CodeCompletionLoc;
- /// \brief The start location for the file of the code-completion point.
+ /// The start location for the file of the code-completion point.
///
/// This gets instantiated when the CodeCompletionFile gets \#include'ed
/// for preprocessing.
SourceLocation CodeCompletionFileLoc;
- /// \brief The source location of the \c import contextual keyword we just
+ /// The source location of the \c import contextual keyword we just
/// lexed, if any.
SourceLocation ModuleImportLoc;
- /// \brief The module import path that we're currently processing.
+ /// The module import path that we're currently processing.
SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath;
- /// \brief Whether the last token we lexed was an '@'.
+ /// Whether the last token we lexed was an '@'.
bool LastTokenWasAt = false;
- /// \brief Whether the module import expects an identifier next. Otherwise,
+ /// Whether the module import expects an identifier next. Otherwise,
/// it expects a '.' or ';'.
bool ModuleImportExpectsIdentifier = false;
- /// \brief The source location of the currently-active
+ /// The source location of the currently-active
/// \#pragma clang arc_cf_code_audited begin.
SourceLocation PragmaARCCFCodeAuditedLoc;
- /// \brief The source location of the currently-active
+ /// The source location of the currently-active
/// \#pragma clang assume_nonnull begin.
SourceLocation PragmaAssumeNonNullLoc;
- /// \brief True if we hit the code-completion point.
+ /// True if we hit the code-completion point.
bool CodeCompletionReached = false;
- /// \brief The code completion token containing the information
+ /// The code completion token containing the information
/// on the stem that is to be code completed.
IdentifierInfo *CodeCompletionII = nullptr;
- /// \brief The directory that the main file should be considered to occupy,
+ /// The directory that the main file should be considered to occupy,
/// if it does not correspond to a real file (as happens when building a
/// module).
const DirectoryEntry *MainFileDir = nullptr;
- /// \brief The number of bytes that we will initially skip when entering the
+ /// The number of bytes that we will initially skip when entering the
/// main file, along with a flag that indicates whether skipping this number
/// of bytes will place the lexer at the start of a line.
///
@@ -386,37 +386,37 @@ private:
State ConditionalStackState = Off;
} PreambleConditionalStack;
- /// \brief The current top of the stack that we're lexing from if
+ /// The current top of the stack that we're lexing from if
/// not expanding a macro and we are lexing directly from source code.
///
/// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
std::unique_ptr<Lexer> CurLexer;
- /// \brief The current top of stack that we're lexing from if
+ /// The current top of stack that we're lexing from if
/// not expanding from a macro and we are lexing from a PTH cache.
///
/// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
std::unique_ptr<PTHLexer> CurPTHLexer;
- /// \brief The current top of the stack what we're lexing from
+ /// The current top of the stack what we're lexing from
/// if not expanding a macro.
///
/// This is an alias for either CurLexer or CurPTHLexer.
PreprocessorLexer *CurPPLexer = nullptr;
- /// \brief Used to find the current FileEntry, if CurLexer is non-null
+ /// Used to find the current FileEntry, if CurLexer is non-null
/// and if applicable.
///
/// This allows us to implement \#include_next and find directory-specific
/// properties.
const DirectoryLookup *CurDirLookup = nullptr;
- /// \brief The current macro we are expanding, if we are expanding a macro.
+ /// The current macro we are expanding, if we are expanding a macro.
///
/// One of CurLexer and CurTokenLexer must be null.
std::unique_ptr<TokenLexer> CurTokenLexer;
- /// \brief The kind of lexer we're currently working with.
+ /// The kind of lexer we're currently working with.
enum CurLexerKind {
CLK_Lexer,
CLK_PTHLexer,
@@ -425,11 +425,11 @@ private:
CLK_LexAfterModuleImport
} CurLexerKind = CLK_Lexer;
- /// \brief If the current lexer is for a submodule that is being built, this
+ /// If the current lexer is for a submodule that is being built, this
/// is that submodule.
Module *CurLexerSubmodule = nullptr;
- /// \brief Keeps track of the stack of files currently
+ /// Keeps track of the stack of files currently
/// \#included, and macros currently being expanded from, not counting
/// CurLexer/CurTokenLexer.
struct IncludeStackInfo {
@@ -458,7 +458,7 @@ private:
};
std::vector<IncludeStackInfo> IncludeMacroStack;
- /// \brief Actions invoked when some preprocessor activity is
+ /// Actions invoked when some preprocessor activity is
/// encountered (e.g. a file is \#included, etc).
std::unique_ptr<PPCallbacks> Callbacks;
@@ -617,7 +617,7 @@ private:
struct SubmoduleState;
- /// \brief Information about a submodule that we're currently building.
+ /// Information about a submodule that we're currently building.
struct BuildingSubmoduleInfo {
/// The module that we are building.
Module *M;
@@ -643,7 +643,7 @@ private:
};
SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
- /// \brief Information about a submodule's preprocessor state.
+ /// Information about a submodule's preprocessor state.
struct SubmoduleState {
/// The macros for the submodule.
MacroMap Macros;
@@ -674,7 +674,7 @@ private:
llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro *>>
LeafModuleMacros;
- /// \brief Macros that we want to warn because they are not used at the end
+ /// Macros that we want to warn because they are not used at the end
/// of the translation unit.
///
/// We store just their SourceLocations instead of
@@ -686,7 +686,7 @@ private:
using WarnUnusedMacroLocsTy = llvm::SmallPtrSet<SourceLocation, 32>;
WarnUnusedMacroLocsTy WarnUnusedMacroLocs;
- /// \brief A "freelist" of MacroArg objects that can be
+ /// A "freelist" of MacroArg objects that can be
/// reused for quick allocation.
MacroArgs *MacroArgCache = nullptr;
@@ -713,21 +713,27 @@ private:
unsigned NumFastTokenPaste = 0;
unsigned NumSkipped = 0;
- /// \brief The predefined macros that preprocessor should use from the
+ /// The predefined macros that preprocessor should use from the
/// command line etc.
std::string Predefines;
- /// \brief The file ID for the preprocessor predefines.
+ /// The file ID for the preprocessor predefines.
FileID PredefinesFileID;
+ /// The file ID for the PCH through header.
+ FileID PCHThroughHeaderFileID;
+
+ /// Whether tokens are being skipped until the through header is seen.
+ bool SkippingUntilPCHThroughHeader = false;
+
/// \{
- /// \brief Cache of macro expanders to reduce malloc traffic.
+ /// Cache of macro expanders to reduce malloc traffic.
enum { TokenLexerCacheSize = 8 };
unsigned NumCachedTokenLexers;
std::unique_ptr<TokenLexer> TokenLexerCache[TokenLexerCacheSize];
/// \}
- /// \brief Keeps macro expanded tokens for TokenLexers.
+ /// Keeps macro expanded tokens for TokenLexers.
//
/// Works like a stack; a TokenLexer adds the macro expanded tokens that is
/// going to lex in the cache and when it finishes the tokens are removed
@@ -735,7 +741,7 @@ private:
SmallVector<Token, 16> MacroExpandedTokens;
std::vector<std::pair<TokenLexer *, size_t>> MacroExpandingLexersStack;
- /// \brief A record of the macro definitions and expansions that
+ /// A record of the macro definitions and expansions that
/// occurred during preprocessing.
///
/// This is an optional side structure that can be enabled with
@@ -745,18 +751,18 @@ private:
/// Cached tokens state.
using CachedTokensTy = SmallVector<Token, 1>;
- /// \brief Cached tokens are stored here when we do backtracking or
+ /// Cached tokens are stored here when we do backtracking or
/// lookahead. They are "lexed" by the CachingLex() method.
CachedTokensTy CachedTokens;
- /// \brief The position of the cached token that CachingLex() should
+ /// The position of the cached token that CachingLex() should
/// "lex" next.
///
/// If it points beyond the CachedTokens vector, it means that a normal
/// Lex() should be invoked.
CachedTokensTy::size_type CachedLexPos = 0;
- /// \brief Stack of backtrack positions, allowing nested backtracks.
+ /// Stack of backtrack positions, allowing nested backtracks.
///
/// The EnableBacktrackAtThisPos() method pushes a position to
/// indicate where CachedLexPos should be set when the BackTrack() method is
@@ -785,7 +791,7 @@ public:
~Preprocessor();
- /// \brief Initialize the preprocessor using information about the target.
+ /// Initialize the preprocessor using information about the target.
///
/// \param Target is owned by the caller and must remain valid for the
/// lifetime of the preprocessor.
@@ -794,7 +800,7 @@ public:
void Initialize(const TargetInfo &Target,
const TargetInfo *AuxTarget = nullptr);
- /// \brief Initialize the preprocessor to parse a model file
+ /// Initialize the preprocessor to parse a model file
///
/// To parse model files the preprocessor of the original source is reused to
/// preserver the identifier table. However to avoid some duplicate
@@ -802,10 +808,10 @@ public:
/// to parse model files. This method does that cleanup.
void InitializeForModelFile();
- /// \brief Cleanup after model file parsing
+ /// Cleanup after model file parsing
void FinalizeForModelFile();
- /// \brief Retrieve the preprocessor options used to initialize this
+ /// Retrieve the preprocessor options used to initialize this
/// preprocessor.
PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; }
@@ -838,19 +844,19 @@ public:
return ExternalSource;
}
- /// \brief Retrieve the module loader associated with this preprocessor.
+ /// Retrieve the module loader associated with this preprocessor.
ModuleLoader &getModuleLoader() const { return TheModuleLoader; }
bool hadModuleLoaderFatalFailure() const {
return TheModuleLoader.HadFatalFailure;
}
- /// \brief True if we are currently preprocessing a #if or #elif directive
+ /// True if we are currently preprocessing a #if or #elif directive
bool isParsingIfOrElifDirective() const {
return ParsingIfOrElifDirective;
}
- /// \brief Control whether the preprocessor retains comments in output.
+ /// Control whether the preprocessor retains comments in output.
void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
this->KeepComments = KeepComments | KeepMacroComments;
this->KeepMacroComments = KeepMacroComments;
@@ -879,32 +885,32 @@ public:
/// false if it is producing tokens to be consumed by Parse and Sema.
bool isPreprocessedOutput() const { return PreprocessedOutput; }
- /// \brief Return true if we are lexing directly from the specified lexer.
+ /// Return true if we are lexing directly from the specified lexer.
bool isCurrentLexer(const PreprocessorLexer *L) const {
return CurPPLexer == L;
}
- /// \brief Return the current lexer being lexed from.
+ /// Return the current lexer being lexed from.
///
/// Note that this ignores any potentially active macro expansions and _Pragma
/// expansions going on at the time.
PreprocessorLexer *getCurrentLexer() const { return CurPPLexer; }
- /// \brief Return the current file lexer being lexed from.
+ /// Return the current file lexer being lexed from.
///
/// Note that this ignores any potentially active macro expansions and _Pragma
/// expansions going on at the time.
PreprocessorLexer *getCurrentFileLexer() const;
- /// \brief Return the submodule owning the file being lexed. This may not be
+ /// Return the submodule owning the file being lexed. This may not be
/// the current module if we have changed modules since entering the file.
Module *getCurrentLexerSubmodule() const { return CurLexerSubmodule; }
- /// \brief Returns the FileID for the preprocessor predefines.
+ /// Returns the FileID for the preprocessor predefines.
FileID getPredefinesFileID() const { return PredefinesFileID; }
/// \{
- /// \brief Accessors for preprocessor callbacks.
+ /// Accessors for preprocessor callbacks.
///
/// Note that this class takes ownership of any PPCallbacks object given to
/// it.
@@ -925,7 +931,7 @@ public:
(!getLangOpts().Modules || (bool)getMacroDefinition(II));
}
- /// \brief Determine whether II is defined as a macro within the module M,
+ /// Determine whether II is defined as a macro within the module M,
/// if that is a module that we've already preprocessed. Does not check for
/// macros imported into M.
bool isMacroDefinedInLocalModule(const IdentifierInfo *II, Module *M) {
@@ -969,7 +975,7 @@ public:
S.isAmbiguous(*this, II));
}
- /// \brief Given an identifier, return its latest non-imported MacroDirective
+ /// Given an identifier, return its latest non-imported MacroDirective
/// if it is \#define'd and not \#undef'd, or null if it isn't \#define'd.
MacroDirective *getLocalMacroDirective(const IdentifierInfo *II) const {
if (!II->hasMacroDefinition())
@@ -994,14 +1000,14 @@ public:
return nullptr;
}
- /// \brief Given an identifier, return the latest non-imported macro
+ /// Given an identifier, return the latest non-imported macro
/// directive for that identifier.
///
/// One can iterate over all previous macro directives from the most recent
/// one.
MacroDirective *getLocalMacroDirectiveHistory(const IdentifierInfo *II) const;
- /// \brief Add a directive to the macro directive history for this identifier.
+ /// Add a directive to the macro directive history for this identifier.
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD);
DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI,
SourceLocation Loc) {
@@ -1014,16 +1020,16 @@ public:
return appendDefMacroDirective(II, MI, MI->getDefinitionLoc());
}
- /// \brief Set a MacroDirective that was loaded from a PCH file.
+ /// Set a MacroDirective that was loaded from a PCH file.
void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED,
MacroDirective *MD);
- /// \brief Register an exported macro for a module and identifier.
+ /// Register an exported macro for a module and identifier.
ModuleMacro *addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides, bool &IsNew);
ModuleMacro *getModuleMacro(Module *Mod, IdentifierInfo *II);
- /// \brief Get the list of leaf (non-overridden) module macros for a name.
+ /// Get the list of leaf (non-overridden) module macros for a name.
ArrayRef<ModuleMacro*> getLeafModuleMacros(const IdentifierInfo *II) const {
if (II->isOutOfDate())
updateOutOfDateIdentifier(const_cast<IdentifierInfo&>(*II));
@@ -1041,15 +1047,17 @@ public:
macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
macro_iterator macro_end(bool IncludeExternalMacros = true) const;
- llvm::iterator_range<macro_iterator>
+ llvm::iterator_range<macro_iterator>
macros(bool IncludeExternalMacros = true) const {
- return llvm::make_range(macro_begin(IncludeExternalMacros),
- macro_end(IncludeExternalMacros));
+ macro_iterator begin = macro_begin(IncludeExternalMacros);
+ macro_iterator end = macro_end(IncludeExternalMacros);
+ return llvm::make_range(begin, end);
}
+
/// \}
- /// \brief Return the name of the macro defined before \p Loc that has
+ /// Return the name of the macro defined before \p Loc that has
/// spelling \p Tokens. If there are multiple macros with same spelling,
/// return the last one defined.
StringRef getLastMacroWithSpelling(SourceLocation Loc,
@@ -1057,7 +1065,7 @@ public:
const std::string &getPredefines() const { return Predefines; }
- /// \brief Set the predefines for this Preprocessor.
+ /// Set the predefines for this Preprocessor.
///
/// These predefines are automatically injected when parsing the main file.
void setPredefines(const char *P) { Predefines = P; }
@@ -1069,7 +1077,7 @@ public:
return &Identifiers.get(Name);
}
- /// \brief Add the specified pragma handler to this preprocessor.
+ /// Add the specified pragma handler to this preprocessor.
///
/// If \p Namespace is non-null, then it is a token required to exist on the
/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
@@ -1078,7 +1086,7 @@ public:
AddPragmaHandler(StringRef(), Handler);
}
- /// \brief Remove the specific pragma handler from this preprocessor.
+ /// Remove the specific pragma handler from this preprocessor.
///
/// If \p Namespace is non-null, then it should be the namespace that
/// \p Handler was added to. It is an error to remove a handler that
@@ -1091,68 +1099,84 @@ public:
/// Install empty handlers for all pragmas (making them ignored).
void IgnorePragmas();
- /// \brief Add the specified comment handler to the preprocessor.
+ /// Add the specified comment handler to the preprocessor.
void addCommentHandler(CommentHandler *Handler);
- /// \brief Remove the specified comment handler.
+ /// Remove the specified comment handler.
///
/// It is an error to remove a handler that has not been registered.
void removeCommentHandler(CommentHandler *Handler);
- /// \brief Set the code completion handler to the given object.
+ /// Set the code completion handler to the given object.
void setCodeCompletionHandler(CodeCompletionHandler &Handler) {
CodeComplete = &Handler;
}
- /// \brief Retrieve the current code-completion handler.
+ /// Retrieve the current code-completion handler.
CodeCompletionHandler *getCodeCompletionHandler() const {
return CodeComplete;
}
- /// \brief Clear out the code completion handler.
+ /// Clear out the code completion handler.
void clearCodeCompletionHandler() {
CodeComplete = nullptr;
}
- /// \brief Hook used by the lexer to invoke the "natural language" code
+ /// Hook used by the lexer to invoke the "natural language" code
/// completion point.
void CodeCompleteNaturalLanguage();
- /// \brief Set the code completion token for filtering purposes.
+ /// Set the code completion token for filtering purposes.
void setCodeCompletionIdentifierInfo(IdentifierInfo *Filter) {
CodeCompletionII = Filter;
}
- /// \brief Get the code completion token for filtering purposes.
+ /// Get the code completion token for filtering purposes.
StringRef getCodeCompletionFilter() {
if (CodeCompletionII)
return CodeCompletionII->getName();
return {};
}
- /// \brief Retrieve the preprocessing record, or NULL if there is no
+ /// Retrieve the preprocessing record, or NULL if there is no
/// preprocessing record.
PreprocessingRecord *getPreprocessingRecord() const { return Record; }
- /// \brief Create a new preprocessing record, which will keep track of
+ /// Create a new preprocessing record, which will keep track of
/// all macro expansions, macro definitions, etc.
void createPreprocessingRecord();
- /// \brief Enter the specified FileID as the main source file,
+ /// Returns true if the FileEntry is the PCH through header.
+ bool isPCHThroughHeader(const FileEntry *File);
+
+ /// True if creating a PCH with a through header.
+ bool creatingPCHWithThroughHeader();
+
+ /// True if using a PCH with a through header.
+ bool usingPCHWithThroughHeader();
+
+ /// Skip tokens until after the #include of the through header.
+ void SkipTokensUntilPCHThroughHeader();
+
+ /// Process directives while skipping until the through header is found.
+ void HandleSkippedThroughHeaderDirective(Token &Result,
+ SourceLocation HashLoc);
+
+ /// Enter the specified FileID as the main source file,
/// which implicitly adds the builtin defines etc.
void EnterMainSourceFile();
- /// \brief Inform the preprocessor callbacks that processing is complete.
+ /// Inform the preprocessor callbacks that processing is complete.
void EndSourceFile();
- /// \brief Add a source file to the top of the include stack and
+ /// Add a source file to the top of the include stack and
/// start lexing tokens from it instead of the current buffer.
///
/// Emits a diagnostic, doesn't enter the file, and returns true on error.
bool EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
SourceLocation Loc);
- /// \brief Add a Macro to the top of the include stack and start lexing
+ /// Add a Macro to the top of the include stack and start lexing
/// tokens from it instead of the current buffer.
///
/// \param Args specifies the tokens input to a function-like macro.
@@ -1161,7 +1185,7 @@ public:
void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroInfo *Macro,
MacroArgs *Args);
- /// \brief Add a "macro" context to the top of the include stack,
+ /// Add a "macro" context to the top of the include stack,
/// which will cause the lexer to start returning the specified tokens.
///
/// If \p DisableMacroExpansion is true, tokens lexed from the token stream
@@ -1186,7 +1210,7 @@ public:
EnterTokenStream(Toks.data(), Toks.size(), DisableMacroExpansion, false);
}
- /// \brief Pop the current lexer/macro exp off the top of the lexer stack.
+ /// Pop the current lexer/macro exp off the top of the lexer stack.
///
/// This should only be used in situations where the current state of the
/// top-of-stack lexer is known.
@@ -1207,7 +1231,7 @@ public:
///
void EnableBacktrackAtThisPos();
- /// \brief Disable the last EnableBacktrackAtThisPos call.
+ /// Disable the last EnableBacktrackAtThisPos call.
void CommitBacktrackedTokens();
struct CachedTokensRange {
@@ -1215,28 +1239,28 @@ public:
};
private:
- /// \brief A range of cached tokens that should be erased after lexing
+ /// A range of cached tokens that should be erased after lexing
/// when backtracking requires the erasure of such cached tokens.
Optional<CachedTokensRange> CachedTokenRangeToErase;
public:
- /// \brief Returns the range of cached tokens that were lexed since
+ /// Returns the range of cached tokens that were lexed since
/// EnableBacktrackAtThisPos() was previously called.
CachedTokensRange LastCachedTokenRange();
- /// \brief Erase the range of cached tokens that were lexed since
+ /// Erase the range of cached tokens that were lexed since
/// EnableBacktrackAtThisPos() was previously called.
void EraseCachedTokens(CachedTokensRange TokenRange);
- /// \brief Make Preprocessor re-lex the tokens that were lexed since
+ /// Make Preprocessor re-lex the tokens that were lexed since
/// EnableBacktrackAtThisPos() was previously called.
void Backtrack();
- /// \brief True if EnableBacktrackAtThisPos() was called and
+ /// True if EnableBacktrackAtThisPos() was called and
/// caching of tokens is on.
bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); }
- /// \brief Lex the next token for this preprocessor.
+ /// Lex the next token for this preprocessor.
void Lex(Token &Result);
void LexAfterModuleImport(Token &Result);
@@ -1247,7 +1271,7 @@ public:
return CurSubmoduleState->VisibleModules.getImportLoc(M);
}
- /// \brief Lex a string literal, which may be the concatenation of multiple
+ /// Lex a string literal, which may be the concatenation of multiple
/// string literals and may even come from macro expansion.
/// \returns true on success, false if a error diagnostic has been generated.
bool LexStringLiteral(Token &Result, std::string &String,
@@ -1260,13 +1284,13 @@ public:
AllowMacroExpansion);
}
- /// \brief Complete the lexing of a string literal where the first token has
+ /// Complete the lexing of a string literal where the first token has
/// already been lexed (see LexStringLiteral).
bool FinishLexStringLiteral(Token &Result, std::string &String,
const char *DiagnosticTag,
bool AllowMacroExpansion);
- /// \brief Lex a token. If it's a comment, keep lexing until we get
+ /// Lex a token. If it's a comment, keep lexing until we get
/// something not a comment.
///
/// This is useful in -E -C mode where comments would foul up preprocessor
@@ -1277,7 +1301,7 @@ public:
while (Result.getKind() == tok::comment);
}
- /// \brief Just like Lex, but disables macro expansion of identifier tokens.
+ /// Just like Lex, but disables macro expansion of identifier tokens.
void LexUnexpandedToken(Token &Result) {
// Disable macro expansion.
bool OldVal = DisableMacroExpansion;
@@ -1289,7 +1313,7 @@ public:
DisableMacroExpansion = OldVal;
}
- /// \brief Like LexNonComment, but this disables macro expansion of
+ /// Like LexNonComment, but this disables macro expansion of
/// identifier tokens.
void LexUnexpandedNonComment(Token &Result) {
do
@@ -1297,7 +1321,7 @@ public:
while (Result.getKind() == tok::comment);
}
- /// \brief Parses a simple integer literal to get its numeric value. Floating
+ /// Parses a simple integer literal to get its numeric value. Floating
/// point literals and user defined literals are rejected. Used primarily to
/// handle pragmas that accept integer arguments.
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value);
@@ -1308,7 +1332,7 @@ public:
MacroExpansionInDirectivesOverride = true;
}
- /// \brief Peeks ahead N tokens and returns that token without consuming any
+ /// Peeks ahead N tokens and returns that token without consuming any
/// tokens.
///
/// LookAhead(0) returns the next token that would be returned by Lex(),
@@ -1322,7 +1346,7 @@ public:
return PeekAhead(N+1);
}
- /// \brief When backtracking is enabled and tokens are cached,
+ /// When backtracking is enabled and tokens are cached,
/// this allows to revert a specific number of tokens.
///
/// Note that the number of tokens being reverted should be up to the last
@@ -1337,7 +1361,7 @@ public:
CachedLexPos -= N;
}
- /// \brief Enters a token in the token stream to be lexed next.
+ /// Enters a token in the token stream to be lexed next.
///
/// If BackTrack() is called afterwards, the token will remain at the
/// insertion point.
@@ -1367,18 +1391,18 @@ public:
return CachedTokens[CachedLexPos-1].getLastLoc();
}
- /// \brief Whether \p Tok is the most recent token (`CachedLexPos - 1`) in
+ /// Whether \p Tok is the most recent token (`CachedLexPos - 1`) in
/// CachedTokens.
bool IsPreviousCachedToken(const Token &Tok) const;
- /// \brief Replace token in `CachedLexPos - 1` in CachedTokens by the tokens
+ /// Replace token in `CachedLexPos - 1` in CachedTokens by the tokens
/// in \p NewToks.
///
/// Useful when a token needs to be split in smaller ones and CachedTokens
/// most recent token must to be updated to reflect that.
void ReplacePreviousCachedToken(ArrayRef<Token> NewToks);
- /// \brief Replace the last token with an annotation token.
+ /// Replace the last token with an annotation token.
///
/// Like AnnotateCachedTokens(), this routine replaces an
/// already-parsed (and resolved) token with an annotation
@@ -1404,19 +1428,19 @@ public:
CachedTokens[CachedLexPos-1] = Tok;
}
- /// \brief Recompute the current lexer kind based on the CurLexer/CurPTHLexer/
+ /// Recompute the current lexer kind based on the CurLexer/CurPTHLexer/
/// CurTokenLexer pointers.
void recomputeCurLexerKind();
- /// \brief Returns true if incremental processing is enabled
+ /// Returns true if incremental processing is enabled
bool isIncrementalProcessingEnabled() const { return IncrementalProcessing; }
- /// \brief Enables the incremental processing
+ /// Enables the incremental processing
void enableIncrementalProcessing(bool value = true) {
IncrementalProcessing = value;
}
- /// \brief Specify the point at which code-completion will be performed.
+ /// Specify the point at which code-completion will be performed.
///
/// \param File the file in which code completion should occur. If
/// this file is included multiple times, code-completion will
@@ -1433,16 +1457,16 @@ public:
bool SetCodeCompletionPoint(const FileEntry *File,
unsigned Line, unsigned Column);
- /// \brief Determine if we are performing code completion.
+ /// Determine if we are performing code completion.
bool isCodeCompletionEnabled() const { return CodeCompletionFile != nullptr; }
- /// \brief Returns the location of the code-completion point.
+ /// Returns the location of the code-completion point.
///
/// Returns an invalid location if code-completion is not enabled or the file
/// containing the code-completion point has not been lexed yet.
SourceLocation getCodeCompletionLoc() const { return CodeCompletionLoc; }
- /// \brief Returns the start location of the file of code-completion point.
+ /// Returns the start location of the file of code-completion point.
///
/// Returns an invalid location if code-completion is not enabled or the file
/// containing the code-completion point has not been lexed yet.
@@ -1450,11 +1474,11 @@ public:
return CodeCompletionFileLoc;
}
- /// \brief Returns true if code-completion is enabled and we have hit the
+ /// Returns true if code-completion is enabled and we have hit the
/// code-completion point.
bool isCodeCompletionReached() const { return CodeCompletionReached; }
- /// \brief Note that we hit the code-completion point.
+ /// Note that we hit the code-completion point.
void setCodeCompletionReached() {
assert(isCodeCompletionEnabled() && "Code-completion not enabled!");
CodeCompletionReached = true;
@@ -1462,7 +1486,7 @@ public:
getDiagnostics().setSuppressAllDiagnostics(true);
}
- /// \brief The location of the currently-active \#pragma clang
+ /// The location of the currently-active \#pragma clang
/// arc_cf_code_audited begin.
///
/// Returns an invalid location if there is no such pragma active.
@@ -1470,13 +1494,13 @@ public:
return PragmaARCCFCodeAuditedLoc;
}
- /// \brief Set the location of the currently-active \#pragma clang
+ /// Set the location of the currently-active \#pragma clang
/// arc_cf_code_audited begin. An invalid location ends the pragma.
void setPragmaARCCFCodeAuditedLoc(SourceLocation Loc) {
PragmaARCCFCodeAuditedLoc = Loc;
}
- /// \brief The location of the currently-active \#pragma clang
+ /// The location of the currently-active \#pragma clang
/// assume_nonnull begin.
///
/// Returns an invalid location if there is no such pragma active.
@@ -1484,19 +1508,19 @@ public:
return PragmaAssumeNonNullLoc;
}
- /// \brief Set the location of the currently-active \#pragma clang
+ /// Set the location of the currently-active \#pragma clang
/// assume_nonnull begin. An invalid location ends the pragma.
void setPragmaAssumeNonNullLoc(SourceLocation Loc) {
PragmaAssumeNonNullLoc = Loc;
}
- /// \brief Set the directory in which the main file should be considered
+ /// Set the directory in which the main file should be considered
/// to have been found, if it is not a real file.
void setMainFileDir(const DirectoryEntry *Dir) {
MainFileDir = Dir;
}
- /// \brief Instruct the preprocessor to skip part of the main source file.
+ /// Instruct the preprocessor to skip part of the main source file.
///
/// \param Bytes The number of bytes in the preamble to skip.
///
@@ -1531,7 +1555,7 @@ public:
return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid);
}
- /// \brief Return the 'spelling' of the Tok token.
+ /// Return the 'spelling' of the Tok token.
///
/// The spelling of a token is the characters used to represent the token in
/// the source file after trigraph expansion and escaped-newline folding. In
@@ -1543,7 +1567,7 @@ public:
return Lexer::getSpelling(Tok, SourceMgr, LangOpts, Invalid);
}
- /// \brief Get the spelling of a token into a preallocated buffer, instead
+ /// Get the spelling of a token into a preallocated buffer, instead
/// of as an std::string.
///
/// The caller is required to allocate enough space for the token, which is
@@ -1560,7 +1584,7 @@ public:
return Lexer::getSpelling(Tok, Buffer, SourceMgr, LangOpts, Invalid);
}
- /// \brief Get the spelling of a token into a SmallVector.
+ /// Get the spelling of a token into a SmallVector.
///
/// Note that the returned StringRef may not point to the
/// supplied buffer if a copy can be avoided.
@@ -1568,14 +1592,14 @@ public:
SmallVectorImpl<char> &Buffer,
bool *Invalid = nullptr) const;
- /// \brief Relex the token at the specified location.
+ /// Relex the token at the specified location.
/// \returns true if there was a failure, false on success.
bool getRawToken(SourceLocation Loc, Token &Result,
bool IgnoreWhiteSpace = false) {
return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts, IgnoreWhiteSpace);
}
- /// \brief Given a Token \p Tok that is a numeric constant with length 1,
+ /// Given a Token \p Tok that is a numeric constant with length 1,
/// return the character.
char
getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
@@ -1593,7 +1617,7 @@ public:
return *SourceMgr.getCharacterData(Tok.getLocation(), Invalid);
}
- /// \brief Retrieve the name of the immediate macro expansion.
+ /// Retrieve the name of the immediate macro expansion.
///
/// This routine starts from a source location, and finds the name of the
/// macro responsible for its immediate expansion. It looks through any
@@ -1605,7 +1629,7 @@ public:
return Lexer::getImmediateMacroName(Loc, SourceMgr, getLangOpts());
}
- /// \brief Plop the specified string into a scratch buffer and set the
+ /// Plop the specified string into a scratch buffer and set the
/// specified token's location and length to it.
///
/// If specified, the source location provides a location of the expansion
@@ -1614,7 +1638,12 @@ public:
SourceLocation ExpansionLocStart = SourceLocation(),
SourceLocation ExpansionLocEnd = SourceLocation());
- /// \brief Computes the source location just past the end of the
+ /// Split the first Length characters out of the token starting at TokLoc
+ /// and return a location pointing to the split token. Re-lexing from the
+ /// split token will return the split token rather than the original.
+ SourceLocation SplitToken(SourceLocation TokLoc, unsigned Length);
+
+ /// Computes the source location just past the end of the
/// token at this source location.
///
/// This routine can be used to produce a source location that
@@ -1633,7 +1662,7 @@ public:
return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts);
}
- /// \brief Returns true if the given MacroID location points at the first
+ /// Returns true if the given MacroID location points at the first
/// token of the macro expansion.
///
/// \param MacroBegin If non-null and function returns true, it is set to
@@ -1644,7 +1673,7 @@ public:
MacroBegin);
}
- /// \brief Returns true if the given MacroID location points at the last
+ /// Returns true if the given MacroID location points at the last
/// token of the macro expansion.
///
/// \param MacroEnd If non-null and function returns true, it is set to
@@ -1654,20 +1683,20 @@ public:
return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, LangOpts, MacroEnd);
}
- /// \brief Print the token to stderr, used for debugging.
+ /// Print the token to stderr, used for debugging.
void DumpToken(const Token &Tok, bool DumpFlags = false) const;
void DumpLocation(SourceLocation Loc) const;
void DumpMacro(const MacroInfo &MI) const;
void dumpMacroInfo(const IdentifierInfo *II);
- /// \brief Given a location that specifies the start of a
+ /// Given a location that specifies the start of a
/// token, return a new location that specifies a character within the token.
SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
unsigned Char) const {
return Lexer::AdvanceToTokenCharacter(TokStart, Char, SourceMgr, LangOpts);
}
- /// \brief Increment the counters for the number of token paste operations
+ /// Increment the counters for the number of token paste operations
/// performed.
///
/// If fast was specified, this is a 'fast paste' case we handled.
@@ -1700,13 +1729,13 @@ private:
llvm::DenseMap<IdentifierInfo*,unsigned> PoisonReasons;
public:
- /// \brief Specifies the reason for poisoning an identifier.
+ /// Specifies the reason for poisoning an identifier.
///
/// If that identifier is accessed while poisoned, then this reason will be
/// used instead of the default "poisoned" diagnostic.
void SetPoisonReason(IdentifierInfo *II, unsigned DiagID);
- /// \brief Display reason for poisoned identifier.
+ /// Display reason for poisoned identifier.
void HandlePoisonedIdentifier(Token & Tok);
void MaybeHandlePoisonedIdentifier(Token & Identifier) {
@@ -1739,7 +1768,7 @@ private:
public:
void PoisonSEHIdentifiers(bool Poison = true); // Borland
- /// \brief Callback invoked when the lexer reads an identifier and has
+ /// Callback invoked when the lexer reads an identifier and has
/// filled in the tokens IdentifierInfo member.
///
/// This callback potentially macro expands it or turns it into a named
@@ -1749,36 +1778,36 @@ public:
/// lex again.
bool HandleIdentifier(Token &Identifier);
- /// \brief Callback invoked when the lexer hits the end of the current file.
+ /// Callback invoked when the lexer hits the end of the current file.
///
/// This either returns the EOF token and returns true, or
/// pops a level off the include stack and returns false, at which point the
/// client should call lex again.
bool HandleEndOfFile(Token &Result, bool isEndOfMacro = false);
- /// \brief Callback invoked when the current TokenLexer hits the end of its
+ /// Callback invoked when the current TokenLexer hits the end of its
/// token stream.
bool HandleEndOfTokenLexer(Token &Result);
- /// \brief Callback invoked when the lexer sees a # token at the start of a
+ /// Callback invoked when the lexer sees a # token at the start of a
/// line.
///
/// This consumes the directive, modifies the lexer/preprocessor state, and
/// advances the lexer(s) so that the next token read is the correct one.
void HandleDirective(Token &Result);
- /// \brief Ensure that the next token is a tok::eod token.
+ /// Ensure that the next token is a tok::eod token.
///
/// If not, emit a diagnostic and consume up until the eod.
/// If \p EnableMacros is true, then we consider macros that expand to zero
/// tokens as being ok.
void CheckEndOfDirective(const char *Directive, bool EnableMacros = false);
- /// \brief Read and discard all tokens remaining on the current line until
+ /// Read and discard all tokens remaining on the current line until
/// the tok::eod token is found.
void DiscardUntilEndOfDirective();
- /// \brief Returns true if the preprocessor has seen a use of
+ /// Returns true if the preprocessor has seen a use of
/// __DATE__ or __TIME__ in the file so far.
bool SawDateOrTime() const {
return DATELoc != SourceLocation() || TIMELoc != SourceLocation();
@@ -1786,13 +1815,13 @@ public:
unsigned getCounterValue() const { return CounterValue; }
void setCounterValue(unsigned V) { CounterValue = V; }
- /// \brief Retrieves the module that we're currently building, if any.
+ /// Retrieves the module that we're currently building, if any.
Module *getCurrentModule();
- /// \brief Allocate a new MacroInfo object with the provided SourceLocation.
+ /// Allocate a new MacroInfo object with the provided SourceLocation.
MacroInfo *AllocateMacroInfo(SourceLocation L);
- /// \brief Turn the specified lexer token into a fully checked and spelled
+ /// Turn the specified lexer token into a fully checked and spelled
/// filename, e.g. as an operand of \#include.
///
/// The caller is expected to provide a buffer that is large enough to hold
@@ -1803,7 +1832,7 @@ public:
/// in ""'s.
bool GetIncludeFilenameSpelling(SourceLocation Loc,StringRef &Filename);
- /// \brief Given a "foo" or \<foo> reference, look up the indicated file.
+ /// Given a "foo" or \<foo> reference, look up the indicated file.
///
/// Returns null on failure. \p isAngled indicates whether the file
/// reference is for system \#include's or not (i.e. using <> instead of "").
@@ -1816,17 +1845,17 @@ public:
ModuleMap::KnownHeader *SuggestedModule,
bool *IsMapped, bool SkipCache = false);
- /// \brief Get the DirectoryLookup structure used to find the current
+ /// Get the DirectoryLookup structure used to find the current
/// FileEntry, if CurLexer is non-null and if applicable.
///
/// This allows us to implement \#include_next and find directory-specific
/// properties.
const DirectoryLookup *GetCurDirLookup() { return CurDirLookup; }
- /// \brief Return true if we're in the top-level file, not in a \#include.
+ /// Return true if we're in the top-level file, not in a \#include.
bool isInPrimaryFile() const;
- /// \brief Handle cases where the \#include name is expanded
+ /// Handle cases where the \#include name is expanded
/// from a macro as multiple tokens, which need to be glued together.
///
/// This occurs for code like:
@@ -1842,7 +1871,7 @@ public:
bool ConcatenateIncludeName(SmallString<128> &FilenameBuffer,
SourceLocation &End);
- /// \brief Lex an on-off-switch (C99 6.10.6p2) and verify that it is
+ /// Lex an on-off-switch (C99 6.10.6p2) and verify that it is
/// followed by EOD. Return true if the token is not a valid on-off-switch.
bool LexOnOffSwitch(tok::OnOffSwitch &OOS);
@@ -1891,7 +1920,7 @@ private:
VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc,
bool isPublic);
- /// \brief Lex and validate a macro name, which occurs after a
+ /// Lex and validate a macro name, which occurs after a
/// \#define or \#undef.
///
/// \param MacroNameTok Token that represents the name defined or undefined.
@@ -1935,7 +1964,7 @@ private:
bool FoundNonSkipPortion, bool FoundElse,
SourceLocation ElseLoc = SourceLocation());
- /// \brief A fast PTH version of SkipExcludedConditionalBlock.
+ /// A fast PTH version of SkipExcludedConditionalBlock.
void PTHSkipExcludedConditionalBlock();
/// Information about the result for evaluating an expression for a
@@ -1948,17 +1977,17 @@ private:
bool IncludedUndefinedIds;
};
- /// \brief Evaluate an integer constant expression that may occur after a
+ /// Evaluate an integer constant expression that may occur after a
/// \#if or \#elif directive and return a \p DirectiveEvalResult object.
///
/// If the expression is equivalent to "!defined(X)" return X in IfNDefMacro.
DirectiveEvalResult EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro);
- /// \brief Install the standard preprocessor pragmas:
+ /// Install the standard preprocessor pragmas:
/// \#pragma GCC poison/system_header/dependency and \#pragma once.
void RegisterBuiltinPragmas();
- /// \brief Register builtin macros such as __LINE__ with the identifier table.
+ /// Register builtin macros such as __LINE__ with the identifier table.
void RegisterBuiltinMacros();
/// If an identifier token is read that is to be expanded as a macro, handle
@@ -1966,7 +1995,7 @@ private:
/// otherwise the caller should lex again.
bool HandleMacroExpandedIdentifier(Token &Tok, const MacroDefinition &MD);
- /// \brief Cache macro expanded tokens for TokenLexers.
+ /// Cache macro expanded tokens for TokenLexers.
//
/// Works like a stack; a TokenLexer adds the macro expanded tokens that is
/// going to lex in the cache and when it finishes the tokens are removed
@@ -1986,34 +2015,37 @@ private:
MacroArgs *ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI,
SourceLocation &ExpansionEnd);
- /// \brief If an identifier token is read that is to be expanded
+ /// If an identifier token is read that is to be expanded
/// as a builtin macro, handle it and return the next token as 'Tok'.
void ExpandBuiltinMacro(Token &Tok);
- /// \brief Read a \c _Pragma directive, slice it up, process it, then
+ /// Read a \c _Pragma directive, slice it up, process it, then
/// return the first token after the directive.
/// This assumes that the \c _Pragma token has just been read into \p Tok.
void Handle_Pragma(Token &Tok);
- /// \brief Like Handle_Pragma except the pragma text is not enclosed within
+ /// Like Handle_Pragma except the pragma text is not enclosed within
/// a string literal.
void HandleMicrosoft__pragma(Token &Tok);
- /// \brief Add a lexer to the top of the include stack and
+ /// Add a lexer to the top of the include stack and
/// start lexing tokens from it instead of the current buffer.
void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
- /// \brief Add a lexer to the top of the include stack and
+ /// Add a lexer to the top of the include stack and
/// start getting tokens from it using the PTH cache.
void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);
- /// \brief Set the FileID for the preprocessor predefines.
+ /// Set the FileID for the preprocessor predefines.
void setPredefinesFileID(FileID FID) {
assert(PredefinesFileID.isInvalid() && "PredefinesFileID already set!");
PredefinesFileID = FID;
}
- /// \brief Returns true if we are lexing from a file and not a
+ /// Set the FileID for the PCH through header.
+ void setPCHThroughHeaderFileID(FileID FID);
+
+ /// Returns true if we are lexing from a file and not a
/// pragma or a macro.
static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) {
return L ? !L->isPragmaLexer() : P != nullptr;
@@ -2079,12 +2111,12 @@ public:
DiagnosticsEngine &Diags, Module *M);
// Module inclusion testing.
- /// \brief Find the module that owns the source or header file that
+ /// Find the module that owns the source or header file that
/// \p Loc points to. If the location is in a file that was included
/// into a module, or is outside any module, returns nullptr.
Module *getModuleForLocation(SourceLocation Loc);
- /// \brief We want to produce a diagnostic at location IncLoc concerning a
+ /// We want to produce a diagnostic at location IncLoc concerning a
/// missing module import.
///
/// \param IncLoc The location at which the missing import was detected.
@@ -2127,7 +2159,7 @@ public:
}
private:
- /// \brief After processing predefined file, initialize the conditional stack from
+ /// After processing predefined file, initialize the conditional stack from
/// the preamble.
void replayPreambleConditionalStack();
@@ -2164,12 +2196,12 @@ public:
// has inserted some tokens and getCommentRetentionState() is false.
bool HandleComment(Token &Token, SourceRange Comment);
- /// \brief A macro is used, update information about macros that need unused
+ /// A macro is used, update information about macros that need unused
/// warnings.
void markMacroAsUsed(MacroInfo *MI);
};
-/// \brief Abstract base class that describes a handler that will receive
+/// Abstract base class that describes a handler that will receive
/// source ranges for each of the comments encountered in the source file.
class CommentHandler {
public:
@@ -2180,7 +2212,7 @@ public:
virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) = 0;
};
-/// \brief Registry of pragma handlers added by plugins
+/// Registry of pragma handlers added by plugins
using PragmaHandlerRegistry = llvm::Registry<PragmaHandler>;
} // namespace clang
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
index ff71d11b4511b..bb02725b116f0 100644
--- a/include/clang/Lex/PreprocessorLexer.h
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Defines the PreprocessorLexer interface.
+/// Defines the PreprocessorLexer interface.
//
//===----------------------------------------------------------------------===//
@@ -39,21 +39,21 @@ protected:
/// The SourceManager FileID corresponding to the file being lexed.
const FileID FID;
- /// \brief Number of SLocEntries before lexing the file.
+ /// Number of SLocEntries before lexing the file.
unsigned InitialNumSLocEntries = 0;
//===--------------------------------------------------------------------===//
// Context-specific lexing flags set by the preprocessor.
//===--------------------------------------------------------------------===//
- /// \brief True when parsing \#XXX; turns '\\n' into a tok::eod token.
+ /// True when parsing \#XXX; turns '\\n' into a tok::eod token.
bool ParsingPreprocessorDirective = false;
- /// \brief True after \#include; turns \<xx> into a tok::angle_string_literal
+ /// True after \#include; turns \<xx> into a tok::angle_string_literal
/// token.
bool ParsingFilename = false;
- /// \brief True if in raw mode.
+ /// True if in raw mode.
///
/// Raw mode disables interpretation of tokens and is a far faster mode to
/// lex in than non-raw-mode. This flag:
@@ -68,11 +68,11 @@ protected:
/// Note that in raw mode that the PP pointer may be null.
bool LexingRawMode = false;
- /// \brief A state machine that detects the \#ifndef-wrapping a file
+ /// A state machine that detects the \#ifndef-wrapping a file
/// idiom for the multiple-include optimization.
MultipleIncludeOpt MIOpt;
- /// \brief Information about the set of \#if/\#ifdef/\#ifndef blocks
+ /// Information about the set of \#if/\#ifdef/\#ifndef blocks
/// we are currently in.
SmallVector<PPConditionalInfo, 4> ConditionalStack;
@@ -82,7 +82,7 @@ protected:
virtual void IndirectLex(Token& Result) = 0;
- /// \brief Return the source location for the next observable location.
+ /// Return the source location for the next observable location.
virtual SourceLocation getSourceLocation() = 0;
//===--------------------------------------------------------------------===//
@@ -114,7 +114,7 @@ protected:
return false;
}
- /// \brief Return the top of the conditional stack.
+ /// Return the top of the conditional stack.
/// \pre This requires that there be a conditional active.
PPConditionalInfo &peekConditionalLevel() {
assert(!ConditionalStack.empty() && "No conditionals active!");
@@ -130,23 +130,23 @@ public:
//===--------------------------------------------------------------------===//
// Misc. lexing methods.
- /// \brief After the preprocessor has parsed a \#include, lex and
+ /// After the preprocessor has parsed a \#include, lex and
/// (potentially) macro expand the filename.
///
/// If the sequence parsed is not lexically legal, emit a diagnostic and
/// return a result EOD token.
void LexIncludeFilename(Token &Result);
- /// \brief Inform the lexer whether or not we are currently lexing a
+ /// Inform the lexer whether or not we are currently lexing a
/// preprocessor directive.
void setParsingPreprocessorDirective(bool f) {
ParsingPreprocessorDirective = f;
}
- /// \brief Return true if this lexer is in raw mode or not.
+ /// Return true if this lexer is in raw mode or not.
bool isLexingRawMode() const { return LexingRawMode; }
- /// \brief Return the preprocessor object for this lexer.
+ /// Return the preprocessor object for this lexer.
Preprocessor *getPP() const { return PP; }
FileID getFileID() const {
@@ -155,7 +155,7 @@ public:
return FID;
}
- /// \brief Number of SLocEntries before lexing the file.
+ /// Number of SLocEntries before lexing the file.
unsigned getInitialNumSLocEntries() const {
return InitialNumSLocEntries;
}
@@ -164,7 +164,7 @@ public:
/// getFileID(), this only works for lexers with attached preprocessors.
const FileEntry *getFileEntry() const;
- /// \brief Iterator that traverses the current stack of preprocessor
+ /// Iterator that traverses the current stack of preprocessor
/// conditional directives (\#if/\#ifdef/\#ifndef).
using conditional_iterator =
SmallVectorImpl<PPConditionalInfo>::const_iterator;
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
index 55fc305dc2950..3d7e5ab4a8dc7 100644
--- a/include/clang/Lex/PreprocessorOptions.h
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -27,14 +27,14 @@ class MemoryBuffer;
namespace clang {
-/// \brief Enumerate the kinds of standard library that
+/// Enumerate the kinds of standard library that
enum ObjCXXARCStandardLibraryKind {
ARCXX_nolib,
- /// \brief libc++
+ /// libc++
ARCXX_libcxx,
- /// \brief libstdc++
+ /// libstdc++
ARCXX_libstdcxx
};
@@ -46,48 +46,60 @@ public:
std::vector<std::string> Includes;
std::vector<std::string> MacroIncludes;
- /// \brief Initialize the preprocessor with the compiler and target specific
+ /// Initialize the preprocessor with the compiler and target specific
/// predefines.
bool UsePredefines = true;
- /// \brief Whether we should maintain a detailed record of all macro
+ /// Whether we should maintain a detailed record of all macro
/// definitions and expansions.
bool DetailedRecord = false;
+ /// If non-empty, the filename used in an #include directive in the primary
+ /// source file (or command-line preinclude) that is used to implement
+ /// MSVC-style precompiled headers. When creating a PCH, after the #include
+ /// of this header, the PCH generation stops. When using a PCH, tokens are
+ /// skipped until after an #include of this header is seen.
+ std::string PCHThroughHeader;
+
/// The implicit PCH included at the start of the translation unit, or empty.
std::string ImplicitPCHInclude;
- /// \brief Headers that will be converted to chained PCHs in memory.
+ /// Headers that will be converted to chained PCHs in memory.
std::vector<std::string> ChainedIncludes;
- /// \brief When true, disables most of the normal validation performed on
+ /// When true, disables most of the normal validation performed on
/// precompiled headers.
bool DisablePCHValidation = false;
- /// \brief When true, a PCH with compiler errors will not be rejected.
+ /// When true, a PCH with compiler errors will not be rejected.
bool AllowPCHWithCompilerErrors = false;
- /// \brief Dump declarations that are deserialized from PCH, for testing.
+ /// Dump declarations that are deserialized from PCH, for testing.
bool DumpDeserializedPCHDecls = false;
- /// \brief This is a set of names for decls that we do not want to be
+ /// This is a set of names for decls that we do not want to be
/// deserialized, and we emit an error if they are; for testing purposes.
std::set<std::string> DeserializedPCHDeclsToErrorOn;
- /// \brief If non-zero, the implicit PCH include is actually a precompiled
+ /// If non-zero, the implicit PCH include is actually a precompiled
/// preamble that covers this number of bytes in the main source file.
///
/// The boolean indicates whether the preamble ends at the start of a new
/// line.
std::pair<unsigned, bool> PrecompiledPreambleBytes;
- /// \brief True indicates that a preamble is being generated.
+ /// True indicates that a preamble is being generated.
///
/// When the lexer is done, one of the things that need to be preserved is the
/// conditional #if stack, so the ASTWriter/ASTReader can save/restore it when
/// processing the rest of the file.
bool GeneratePreamble = false;
+ /// Whether to write comment locations into the PCH when building it.
+ /// Reading the comments from the PCH can be a performance hit even if the
+ /// clients don't use them.
+ bool WriteCommentListToPCH = true;
+
/// The implicit PTH input included at the start of the translation unit, or
/// empty.
std::string ImplicitPTHInclude;
@@ -105,22 +117,22 @@ public:
/// When enabled, the preprocessor will construct editor placeholder tokens.
bool LexEditorPlaceholders = true;
- /// \brief True if the SourceManager should report the original file name for
+ /// True if the SourceManager should report the original file name for
/// contents of files that were remapped to other files. Defaults to true.
bool RemappedFilesKeepOriginalName = true;
- /// \brief The set of file remappings, which take existing files on
+ /// The set of file remappings, which take existing files on
/// the system (the first part of each pair) and gives them the
/// contents of other files on the system (the second part of each
/// pair).
std::vector<std::pair<std::string, std::string>> RemappedFiles;
- /// \brief The set of file-to-buffer remappings, which take existing files
+ /// The set of file-to-buffer remappings, which take existing files
/// on the system (the first part of each pair) and gives them the contents
/// of the specified memory buffer (the second part of each pair).
std::vector<std::pair<std::string, llvm::MemoryBuffer *>> RemappedFileBuffers;
- /// \brief Whether the compiler instance should retain (i.e., not free)
+ /// Whether the compiler instance should retain (i.e., not free)
/// the buffers associated with remapped files.
///
/// This flag defaults to false; it can be set true only through direct
@@ -128,12 +140,12 @@ public:
/// compiler invocation and its buffers will be reused.
bool RetainRemappedFileBuffers = false;
- /// \brief The Objective-C++ ARC standard library that we should support,
+ /// The Objective-C++ ARC standard library that we should support,
/// by providing appropriate definitions to retrofit the standard library
/// with support for lifetime-qualified pointers.
ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary = ARCXX_nolib;
- /// \brief Records the set of modules
+ /// Records the set of modules
class FailedModulesSet {
llvm::StringSet<> Failed;
@@ -147,7 +159,7 @@ public:
}
};
- /// \brief The set of modules that failed to build.
+ /// The set of modules that failed to build.
///
/// This pointer will be shared among all of the compiler instances created
/// to (re)build modules, so that once a module fails to build anywhere,
@@ -174,7 +186,7 @@ public:
RemappedFileBuffers.clear();
}
- /// \brief Reset any options that are not considered when building a
+ /// Reset any options that are not considered when building a
/// module.
void resetNonModularOptions() {
Includes.clear();
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 02a1fef70f2bc..633e1d15697b9 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -102,24 +102,24 @@ public:
return is(K1) || isOneOf(K2, Ks...);
}
- /// \brief Return true if this is a raw identifier (when lexing
+ /// Return true if this is a raw identifier (when lexing
/// in raw mode) or a non-keyword identifier (when lexing in non-raw mode).
bool isAnyIdentifier() const {
return tok::isAnyIdentifier(getKind());
}
- /// \brief Return true if this is a "literal", like a numeric
+ /// Return true if this is a "literal", like a numeric
/// constant, string, etc.
bool isLiteral() const {
return tok::isLiteral(getKind());
}
- /// \brief Return true if this is any of tok::annot_* kind tokens.
+ /// Return true if this is any of tok::annot_* kind tokens.
bool isAnnotation() const {
return tok::isAnnotation(getKind());
}
- /// \brief Return a source location identifier for the specified
+ /// Return a source location identifier for the specified
/// offset in the current file.
SourceLocation getLocation() const {
return SourceLocation::getFromRawEncoding(Loc);
@@ -153,7 +153,7 @@ public:
: getLocation().getLocWithOffset(getLength());
}
- /// \brief SourceRange of the group of tokens that this annotation token
+ /// SourceRange of the group of tokens that this annotation token
/// represents.
SourceRange getAnnotationRange() const {
return SourceRange(getLocation(), getAnnotationEndLoc());
@@ -165,7 +165,7 @@ public:
const char *getName() const { return tok::getTokenName(Kind); }
- /// \brief Reset all flags to cleared.
+ /// Reset all flags to cleared.
void startToken() {
Kind = tok::unknown;
Flags = 0;
@@ -230,22 +230,22 @@ public:
PtrData = val;
}
- /// \brief Set the specified flag.
+ /// Set the specified flag.
void setFlag(TokenFlags Flag) {
Flags |= Flag;
}
- /// \brief Get the specified flag.
+ /// Get the specified flag.
bool getFlag(TokenFlags Flag) const {
return (Flags & Flag) != 0;
}
- /// \brief Unset the specified flag.
+ /// Unset the specified flag.
void clearFlag(TokenFlags Flag) {
Flags &= ~Flag;
}
- /// \brief Return the internal represtation of the flags.
+ /// Return the internal represtation of the flags.
///
/// This is only intended for low-level operations such as writing tokens to
/// disk.
@@ -253,7 +253,7 @@ public:
return Flags;
}
- /// \brief Set a flag to either true or false.
+ /// Set a flag to either true or false.
void setFlagValue(TokenFlags Flag, bool Val) {
if (Val)
setFlag(Flag);
@@ -265,28 +265,28 @@ public:
///
bool isAtStartOfLine() const { return getFlag(StartOfLine); }
- /// \brief Return true if this token has whitespace before it.
+ /// Return true if this token has whitespace before it.
///
bool hasLeadingSpace() const { return getFlag(LeadingSpace); }
- /// \brief Return true if this identifier token should never
+ /// Return true if this identifier token should never
/// be expanded in the future, due to C99 6.10.3.4p2.
bool isExpandDisabled() const { return getFlag(DisableExpand); }
- /// \brief Return true if we have an ObjC keyword identifier.
+ /// Return true if we have an ObjC keyword identifier.
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const;
- /// \brief Return the ObjC keyword kind.
+ /// Return the ObjC keyword kind.
tok::ObjCKeywordKind getObjCKeywordID() const;
- /// \brief Return true if this token has trigraphs or escaped newlines in it.
+ /// Return true if this token has trigraphs or escaped newlines in it.
bool needsCleaning() const { return getFlag(NeedsCleaning); }
- /// \brief Return true if this token has an empty macro before it.
+ /// Return true if this token has an empty macro before it.
///
bool hasLeadingEmptyMacro() const { return getFlag(LeadingEmptyMacro); }
- /// \brief Return true if this token is a string or character literal which
+ /// Return true if this token is a string or character literal which
/// has a ud-suffix.
bool hasUDSuffix() const { return getFlag(HasUDSuffix); }
@@ -308,21 +308,21 @@ public:
bool isEditorPlaceholder() const { return getFlag(IsEditorPlaceholder); }
};
-/// \brief Information about the conditional stack (\#if directives)
+/// Information about the conditional stack (\#if directives)
/// currently active.
struct PPConditionalInfo {
- /// \brief Location where the conditional started.
+ /// Location where the conditional started.
SourceLocation IfLoc;
- /// \brief True if this was contained in a skipping directive, e.g.,
+ /// True if this was contained in a skipping directive, e.g.,
/// in a "\#if 0" block.
bool WasSkipping;
- /// \brief True if we have emitted tokens already, and now we're in
+ /// True if we have emitted tokens already, and now we're in
/// an \#else block or something. Only useful in Skipping blocks.
bool FoundNonSkip;
- /// \brief True if we've seen a \#else in this block. If so,
+ /// True if we've seen a \#else in this block. If so,
/// \#elif/\#else directives are not allowed.
bool FoundElse;
};
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
index b8b0beabf2ba2..e616d497eec69 100644
--- a/include/clang/Lex/TokenLexer.h
+++ b/include/clang/Lex/TokenLexer.h
@@ -62,18 +62,18 @@ class TokenLexer {
/// expanded.
SourceLocation ExpandLocStart, ExpandLocEnd;
- /// \brief Source location pointing at the source location entry chunk that
+ /// Source location pointing at the source location entry chunk that
/// was reserved for the current macro expansion.
SourceLocation MacroExpansionStart;
- /// \brief The offset of the macro expansion in the
+ /// The offset of the macro expansion in the
/// "source location address space".
unsigned MacroStartSLocOffset;
- /// \brief Location of the macro definition.
+ /// Location of the macro definition.
SourceLocation MacroDefStart;
- /// \brief Length of the macro definition.
+ /// Length of the macro definition.
unsigned MacroDefLength;
/// Lexical information about the expansion point of the macro: the identifier
@@ -198,7 +198,7 @@ private:
/// the tokens just expanded through __VA_OPT__ processing. These (sub)
/// sequence of tokens are folded into one stringified token.
///
- /// \param[in] VCtx - contains relevent contextual information about the
+ /// \param[in] VCtx - contains relevant contextual information about the
/// state of the tokens around and including the __VA_OPT__ token, necessary
/// for stringification.
void stringifyVAOPTContents(SmallVectorImpl<Token> &ReplacementToks,
@@ -216,12 +216,12 @@ private:
/// first token on the next line.
void HandleMicrosoftCommentPaste(Token &Tok, SourceLocation OpLoc);
- /// \brief If \p loc is a FileID and points inside the current macro
+ /// If \p loc is a FileID and points inside the current macro
/// definition, returns the appropriate source location pointing at the
/// macro expansion source location entry.
SourceLocation getExpansionLocForMacroDefLoc(SourceLocation loc) const;
- /// \brief Creates SLocEntries and updates the locations of macro argument
+ /// Creates SLocEntries and updates the locations of macro argument
/// tokens to their new expanded locations.
///
/// \param ArgIdSpellLoc the location of the macro argument id inside the
diff --git a/include/clang/Lex/VariadicMacroSupport.h b/include/clang/Lex/VariadicMacroSupport.h
index cebaf15187de0..55202ffc34d75 100644
--- a/include/clang/Lex/VariadicMacroSupport.h
+++ b/include/clang/Lex/VariadicMacroSupport.h
@@ -55,7 +55,7 @@ namespace clang {
/// Client code should call this function as soon as the Preprocessor has
/// either completed lexing the macro's definition tokens, or an error
- /// occured and the context is being exited. This function is idempotent
+ /// occurred and the context is being exited. This function is idempotent
/// (might be explicitly called, and then reinvoked via the destructor).
void exitScope() {
Ident__VA_ARGS__->setIsPoisoned(true);
@@ -66,7 +66,7 @@ namespace clang {
~VariadicMacroScopeGuard() { exitScope(); }
};
- /// \brief A class for tracking whether we're inside a VA_OPT during a
+ /// A class for tracking whether we're inside a VA_OPT during a
/// traversal of the tokens of a variadic macro definition.
class VAOptDefinitionContext {
/// Contains all the locations of so far unmatched lparens.
@@ -116,7 +116,7 @@ namespace clang {
};
- /// \brief A class for tracking whether we're inside a VA_OPT during a
+ /// A class for tracking whether we're inside a VA_OPT during a
/// traversal of the tokens of a macro during macro expansion.
class VAOptExpansionContext : VAOptDefinitionContext {
diff --git a/include/clang/Parse/ParseAST.h b/include/clang/Parse/ParseAST.h
index 34c96816ebdf6..34b04060346f8 100644
--- a/include/clang/Parse/ParseAST.h
+++ b/include/clang/Parse/ParseAST.h
@@ -23,7 +23,7 @@ namespace clang {
class CodeCompleteConsumer;
class Sema;
- /// \brief Parse the entire file specified, notifying the ASTConsumer as
+ /// Parse the entire file specified, notifying the ASTConsumer as
/// the file is parsed.
///
/// This operation inserts the parsed decls into the translation
@@ -42,7 +42,7 @@ namespace clang {
CodeCompleteConsumer *CompletionConsumer = nullptr,
bool SkipFunctionBodies = false);
- /// \brief Parse the main file known to the preprocessor, producing an
+ /// Parse the main file known to the preprocessor, producing an
/// abstract syntax tree.
void ParseAST(Sema &S, bool PrintStats = false,
bool SkipFunctionBodies = false);
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 4a25c70956a3b..d7b83803af202 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_PARSE_PARSER_H
#include "clang/AST/Availability.h"
+#include "clang/Basic/BitmaskEnum.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/OperatorPrecedence.h"
#include "clang/Basic/Specifiers.h"
@@ -45,7 +46,6 @@ namespace clang {
class ColonProtectionRAIIObject;
class InMessageExpressionRAIIObject;
class PoisonSEHIdentifiersRAIIObject;
- class VersionTuple;
class OMPClause;
class ObjCTypeParamList;
class ObjCTypeParameter;
@@ -121,25 +121,25 @@ class Parser : public CodeCompletionHandler {
/// Objective-C contextual keywords.
mutable IdentifierInfo *Ident_instancetype;
- /// \brief Identifier for "introduced".
+ /// Identifier for "introduced".
IdentifierInfo *Ident_introduced;
- /// \brief Identifier for "deprecated".
+ /// Identifier for "deprecated".
IdentifierInfo *Ident_deprecated;
- /// \brief Identifier for "obsoleted".
+ /// Identifier for "obsoleted".
IdentifierInfo *Ident_obsoleted;
- /// \brief Identifier for "unavailable".
+ /// Identifier for "unavailable".
IdentifierInfo *Ident_unavailable;
- /// \brief Identifier for "message".
+ /// Identifier for "message".
IdentifierInfo *Ident_message;
- /// \brief Identifier for "strict".
+ /// Identifier for "strict".
IdentifierInfo *Ident_strict;
- /// \brief Identifier for "replacement".
+ /// Identifier for "replacement".
IdentifierInfo *Ident_replacement;
/// Identifiers used by the 'external_source_symbol' attribute.
@@ -179,12 +179,16 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> MSSection;
std::unique_ptr<PragmaHandler> MSRuntimeChecks;
std::unique_ptr<PragmaHandler> MSIntrinsic;
+ std::unique_ptr<PragmaHandler> MSOptimize;
std::unique_ptr<PragmaHandler> CUDAForceHostDeviceHandler;
std::unique_ptr<PragmaHandler> OptimizeHandler;
std::unique_ptr<PragmaHandler> LoopHintHandler;
std::unique_ptr<PragmaHandler> UnrollHintHandler;
std::unique_ptr<PragmaHandler> NoUnrollHintHandler;
std::unique_ptr<PragmaHandler> FPHandler;
+ std::unique_ptr<PragmaHandler> STDCFENVHandler;
+ std::unique_ptr<PragmaHandler> STDCCXLIMITHandler;
+ std::unique_ptr<PragmaHandler> STDCUnknownHandler;
std::unique_ptr<PragmaHandler> AttributePragmaHandler;
std::unique_ptr<CommentHandler> CommentSemaHandler;
@@ -201,7 +205,7 @@ class Parser : public CodeCompletionHandler {
/// ColonProtectionRAIIObject RAII object.
bool ColonIsSacred;
- /// \brief When true, we are directly inside an Objective-C message
+ /// When true, we are directly inside an Objective-C message
/// send expression.
///
/// This is managed by the \c InMessageExpressionRAIIObject class, and
@@ -211,7 +215,7 @@ class Parser : public CodeCompletionHandler {
/// The "depth" of the template parameters currently being parsed.
unsigned TemplateParameterDepth;
- /// \brief RAII class that manages the template parameter depth.
+ /// RAII class that manages the template parameter depth.
class TemplateParameterDepthRAII {
unsigned &Depth;
unsigned AddedLevels;
@@ -234,16 +238,100 @@ class Parser : public CodeCompletionHandler {
unsigned getDepth() const { return Depth; }
};
- /// Factory object for creating AttributeList objects.
+ /// Factory object for creating ParsedAttr objects.
AttributeFactory AttrFactory;
- /// \brief Gathers and cleans up TemplateIdAnnotations when parsing of a
+ /// Gathers and cleans up TemplateIdAnnotations when parsing of a
/// top-level declaration is finished.
SmallVector<TemplateIdAnnotation *, 16> TemplateIds;
- /// \brief Identifiers which have been declared within a tentative parse.
+ /// Identifiers which have been declared within a tentative parse.
SmallVector<IdentifierInfo *, 8> TentativelyDeclaredIdentifiers;
+ /// Tracker for '<' tokens that might have been intended to be treated as an
+ /// angle bracket instead of a less-than comparison.
+ ///
+ /// This happens when the user intends to form a template-id, but typoes the
+ /// template-name or forgets a 'template' keyword for a dependent template
+ /// name.
+ ///
+ /// We track these locations from the point where we see a '<' with a
+ /// name-like expression on its left until we see a '>' or '>>' that might
+ /// match it.
+ struct AngleBracketTracker {
+ /// Flags used to rank candidate template names when there is more than one
+ /// '<' in a scope.
+ enum Priority : unsigned short {
+ /// A non-dependent name that is a potential typo for a template name.
+ PotentialTypo = 0x0,
+ /// A dependent name that might instantiate to a template-name.
+ DependentName = 0x2,
+
+ /// A space appears before the '<' token.
+ SpaceBeforeLess = 0x0,
+ /// No space before the '<' token
+ NoSpaceBeforeLess = 0x1,
+
+ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ DependentName)
+ };
+
+ struct Loc {
+ Expr *TemplateName;
+ SourceLocation LessLoc;
+ AngleBracketTracker::Priority Priority;
+ unsigned short ParenCount, BracketCount, BraceCount;
+
+ bool isActive(Parser &P) const {
+ return P.ParenCount == ParenCount && P.BracketCount == BracketCount &&
+ P.BraceCount == BraceCount;
+ }
+
+ bool isActiveOrNested(Parser &P) const {
+ return isActive(P) || P.ParenCount > ParenCount ||
+ P.BracketCount > BracketCount || P.BraceCount > BraceCount;
+ }
+ };
+
+ SmallVector<Loc, 8> Locs;
+
+ /// Add an expression that might have been intended to be a template name.
+ /// In the case of ambiguity, we arbitrarily select the innermost such
+ /// expression, for example in 'foo < bar < baz', 'bar' is the current
+ /// candidate. No attempt is made to track that 'foo' is also a candidate
+ /// for the case where we see a second suspicious '>' token.
+ void add(Parser &P, Expr *TemplateName, SourceLocation LessLoc,
+ Priority Prio) {
+ if (!Locs.empty() && Locs.back().isActive(P)) {
+ if (Locs.back().Priority <= Prio) {
+ Locs.back().TemplateName = TemplateName;
+ Locs.back().LessLoc = LessLoc;
+ Locs.back().Priority = Prio;
+ }
+ } else {
+ Locs.push_back({TemplateName, LessLoc, Prio,
+ P.ParenCount, P.BracketCount, P.BraceCount});
+ }
+ }
+
+ /// Mark the current potential missing template location as having been
+ /// handled (this happens if we pass a "corresponding" '>' or '>>' token
+ /// or leave a bracket scope).
+ void clear(Parser &P) {
+ while (!Locs.empty() && Locs.back().isActiveOrNested(P))
+ Locs.pop_back();
+ }
+
+ /// Get the current enclosing expression that might hve been intended to be
+ /// a template name.
+ Loc *getCurrent(Parser &P) {
+ if (!Locs.empty() && Locs.back().isActive(P))
+ return &Locs.back();
+ return nullptr;
+ }
+ };
+
+ AngleBracketTracker AngleBrackets;
+
IdentifierInfo *getSEHExceptKeyword();
/// True if we are within an Objective-C container while parsing C-like decls.
@@ -376,15 +464,15 @@ private:
/// isTokenParen - Return true if the cur token is '(' or ')'.
bool isTokenParen() const {
- return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren;
+ return Tok.isOneOf(tok::l_paren, tok::r_paren);
}
/// isTokenBracket - Return true if the cur token is '[' or ']'.
bool isTokenBracket() const {
- return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square;
+ return Tok.isOneOf(tok::l_square, tok::r_square);
}
/// isTokenBrace - Return true if the cur token is '{' or '}'.
bool isTokenBrace() const {
- return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
+ return Tok.isOneOf(tok::l_brace, tok::r_brace);
}
/// isTokenStringLiteral - True if this token is a string-literal.
bool isTokenStringLiteral() const {
@@ -396,11 +484,11 @@ private:
isTokenBrace() || Tok.is(tok::code_completion) || Tok.isAnnotation();
}
- /// \brief Returns true if the current token is '=' or is a type of '='.
+ /// Returns true if the current token is '=' or is a type of '='.
/// For typos, give a fixit to '='
bool isTokenEqualOrEqualTypo();
- /// \brief Return the current token to the token stream and make the given
+ /// Return the current token to the token stream and make the given
/// token the current token.
void UnconsumeToken(Token &Consumed) {
Token Next = Tok;
@@ -423,8 +511,10 @@ private:
assert(isTokenParen() && "wrong consume method");
if (Tok.getKind() == tok::l_paren)
++ParenCount;
- else if (ParenCount)
+ else if (ParenCount) {
+ AngleBrackets.clear(*this);
--ParenCount; // Don't let unbalanced )'s drive the count negative.
+ }
PrevTokLocation = Tok.getLocation();
PP.Lex(Tok);
return PrevTokLocation;
@@ -436,8 +526,10 @@ private:
assert(isTokenBracket() && "wrong consume method");
if (Tok.getKind() == tok::l_square)
++BracketCount;
- else if (BracketCount)
+ else if (BracketCount) {
+ AngleBrackets.clear(*this);
--BracketCount; // Don't let unbalanced ]'s drive the count negative.
+ }
PrevTokLocation = Tok.getLocation();
PP.Lex(Tok);
@@ -450,8 +542,10 @@ private:
assert(isTokenBrace() && "wrong consume method");
if (Tok.getKind() == tok::l_brace)
++BraceCount;
- else if (BraceCount)
+ else if (BraceCount) {
+ AngleBrackets.clear(*this);
--BraceCount; // Don't let unbalanced }'s drive the count negative.
+ }
PrevTokLocation = Tok.getLocation();
PP.Lex(Tok);
@@ -470,7 +564,7 @@ private:
return PrevTokLocation;
}
- /// \brief Consume the current code-completion token.
+ /// Consume the current code-completion token.
///
/// This routine can be called to consume the code-completion token and
/// continue processing in special cases where \c cutOffParsing() isn't
@@ -489,7 +583,7 @@ private:
/// \returns the source location of the code-completion token.
SourceLocation handleUnexpectedCodeCompletionToken();
- /// \brief Abruptly cut off parsing; mainly used when we have reached the
+ /// Abruptly cut off parsing; mainly used when we have reached the
/// code-completion point.
void cutOffParsing() {
if (PP.isCodeCompletionEnabled())
@@ -498,7 +592,7 @@ private:
Tok.setKind(tok::eof);
}
- /// \brief Determine if we're at the end of the file or at a transition
+ /// Determine if we're at the end of the file or at a transition
/// between modules.
bool isEofOrEom() {
tok::TokenKind Kind = Tok.getKind();
@@ -506,34 +600,34 @@ private:
Kind == tok::annot_module_end || Kind == tok::annot_module_include;
}
- /// \brief Checks if the \p Level is valid for use in a fold expression.
+ /// Checks if the \p Level is valid for use in a fold expression.
bool isFoldOperator(prec::Level Level) const;
- /// \brief Checks if the \p Kind is a valid operator for fold expressions.
+ /// Checks if the \p Kind is a valid operator for fold expressions.
bool isFoldOperator(tok::TokenKind Kind) const;
- /// \brief Initialize all pragma handlers.
+ /// Initialize all pragma handlers.
void initializePragmaHandlers();
- /// \brief Destroy and reset all pragma handlers.
+ /// Destroy and reset all pragma handlers.
void resetPragmaHandlers();
- /// \brief Handle the annotation token produced for #pragma unused(...)
+ /// Handle the annotation token produced for #pragma unused(...)
void HandlePragmaUnused();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma GCC visibility...
void HandlePragmaVisibility();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma pack...
void HandlePragmaPack();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma ms_struct...
void HandlePragmaMSStruct();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma comment...
void HandlePragmaMSComment();
@@ -549,43 +643,43 @@ private:
bool HandlePragmaMSInitSeg(StringRef PragmaName,
SourceLocation PragmaLocation);
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma align...
void HandlePragmaAlign();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma clang __debug dump...
void HandlePragmaDump();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma weak id...
void HandlePragmaWeak();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma weak id = id...
void HandlePragmaWeakAlias();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma redefine_extname...
void HandlePragmaRedefineExtname();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma STDC FP_CONTRACT...
void HandlePragmaFPContract();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma clang fp ...
void HandlePragmaFP();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma OPENCL EXTENSION...
void HandlePragmaOpenCLExtension();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma clang __debug captured
StmtResult HandlePragmaCaptured();
- /// \brief Handle the annotation token produced for
+ /// Handle the annotation token produced for
/// #pragma clang loop and #pragma unroll.
bool HandlePragmaLoopHint(LoopHint &Hint);
@@ -624,13 +718,13 @@ private:
Tok.setAnnotationValue(T.getAsOpaquePtr());
}
- /// \brief Read an already-translated primary expression out of an annotation
+ /// Read an already-translated primary expression out of an annotation
/// token.
static ExprResult getExprAnnotation(const Token &Tok) {
return ExprResult::getFromOpaquePointer(Tok.getAnnotationValue());
}
- /// \brief Set the primary expression corresponding to the given annotation
+ /// Set the primary expression corresponding to the given annotation
/// token.
static void setExprAnnotation(Token &Tok, ExprResult ER) {
Tok.setAnnotationValue(ER.getAsOpaquePointer());
@@ -714,7 +808,7 @@ private:
/// otherwise emits a diagnostic and returns true.
bool TryKeywordIdentFallback(bool DisableKeyword);
- /// \brief Get the TemplateIdAnnotation from the token.
+ /// Get the TemplateIdAnnotation from the token.
TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok);
/// TentativeParsingAction - An object that is used as a kind of "tentative
@@ -812,14 +906,14 @@ private:
unsigned Diag = diag::err_expected,
StringRef DiagMsg = "");
- /// \brief The parser expects a semicolon and, if present, will consume it.
+ /// The parser expects a semicolon and, if present, will consume it.
///
/// If the next token is not a semicolon, this emits the specified diagnostic,
/// or, if there's just some closing-delimiter noise (e.g., ')' or ']') prior
/// to the semicolon, consumes that extra token.
bool ExpectAndConsumeSemi(unsigned DiagID);
- /// \brief The kind of extra semi diagnostic to emit.
+ /// The kind of extra semi diagnostic to emit.
enum ExtraSemiKind {
OutsideFunction = 0,
InsideStruct = 1,
@@ -827,7 +921,7 @@ private:
AfterMemberFunctionDefinition = 3
};
- /// \brief Consume any extra semi-colons until the end of the line.
+ /// Consume any extra semi-colons until the end of the line.
void ConsumeExtraSemi(ExtraSemiKind Kind, unsigned TST = TST_unspecified);
/// Return false if the next token is an identifier. An 'expected identifier'
@@ -891,7 +985,7 @@ public:
void ExitScope();
private:
- /// \brief RAII object used to modify the scope flags for the current scope.
+ /// RAII object used to modify the scope flags for the current scope.
class ParseScopeFlags {
Scope *CurScope;
unsigned OldFlags;
@@ -920,10 +1014,10 @@ private:
public:
- /// \brief Control flags for SkipUntil functions.
+ /// Control flags for SkipUntil functions.
enum SkipUntilFlags {
StopAtSemi = 1 << 0, ///< Stop skipping at semicolon
- /// \brief Stop skipping at specified token, but don't skip the token itself
+ /// Stop skipping at specified token, but don't skip the token itself
StopBeforeMatch = 1 << 1,
StopAtCodeCompletion = 1 << 2 ///< Stop at code completion
};
@@ -1045,7 +1139,7 @@ private:
Decl *D;
CachedTokens Toks;
- /// \brief Whether this member function had an associated template
+ /// Whether this member function had an associated template
/// scope. When true, D is a template declaration.
/// otherwise, it is a member function declaration.
bool TemplateScope;
@@ -1091,9 +1185,9 @@ private:
/// Method - The method declaration.
Decl *Method;
- /// \brief Whether this member function had an associated template
+ /// Whether this member function had an associated template
/// scope. When true, D is a template declaration.
- /// othewise, it is a member function declaration.
+ /// otherwise, it is a member function declaration.
bool TemplateScope;
/// DefaultArgs - Contains the parameters of the function and
@@ -1103,7 +1197,7 @@ private:
/// scope at the appropriate times.
SmallVector<LateParsedDefaultArgument, 8> DefaultArgs;
- /// \brief The set of tokens that make up an exception-specification that
+ /// The set of tokens that make up an exception-specification that
/// has not yet been parsed.
CachedTokens *ExceptionSpecTokens;
};
@@ -1135,7 +1229,7 @@ private:
/// entities.
typedef SmallVector<LateParsedDeclaration*,2> LateParsedDeclarationsContainer;
- /// \brief Representation of a class that has been parsed, including
+ /// Representation of a class that has been parsed, including
/// any member function declarations or definitions that need to be
/// parsed after the corresponding top-level class is complete.
struct ParsingClass {
@@ -1143,19 +1237,19 @@ private:
: TopLevelClass(TopLevelClass), TemplateScope(false),
IsInterface(IsInterface), TagOrTemplate(TagOrTemplate) { }
- /// \brief Whether this is a "top-level" class, meaning that it is
+ /// Whether this is a "top-level" class, meaning that it is
/// not nested within another class.
bool TopLevelClass : 1;
- /// \brief Whether this class had an associated template
+ /// Whether this class had an associated template
/// scope. When true, TagOrTemplate is a template declaration;
- /// othewise, it is a tag declaration.
+ /// otherwise, it is a tag declaration.
bool TemplateScope : 1;
- /// \brief Whether this class is an __interface.
+ /// Whether this class is an __interface.
bool IsInterface : 1;
- /// \brief The class or class template whose definition we are parsing.
+ /// The class or class template whose definition we are parsing.
Decl *TagOrTemplate;
/// LateParsedDeclarations - Method declarations, inline definitions and
@@ -1164,7 +1258,7 @@ private:
LateParsedDeclarationsContainer LateParsedDeclarations;
};
- /// \brief The stack of classes that is currently being
+ /// The stack of classes that is currently being
/// parsed. Nested and local classes will be pushed onto this stack
/// when they are parsed, and removed afterward.
std::stack<ParsingClass *> ClassStack;
@@ -1174,7 +1268,7 @@ private:
return *ClassStack.top();
}
- /// \brief RAII object used to manage the parsing of a class definition.
+ /// RAII object used to manage the parsing of a class definition.
class ParsingClassDefinition {
Parser &P;
bool Popped;
@@ -1187,7 +1281,7 @@ private:
State(P.PushParsingClass(TagOrTemplate, TopLevelClass, IsInterface)) {
}
- /// \brief Pop this class of the stack.
+ /// Pop this class of the stack.
void Pop() {
assert(!Popped && "Nested class has already been popped");
Popped = true;
@@ -1200,7 +1294,7 @@ private:
}
};
- /// \brief Contains information about any template-specific
+ /// Contains information about any template-specific
/// information that has been parsed prior to parsing declaration
/// specifiers.
struct ParsedTemplateInfo {
@@ -1220,31 +1314,31 @@ private:
ExternLoc(ExternLoc), TemplateLoc(TemplateLoc),
LastParameterListWasEmpty(false){ }
- /// \brief The kind of template we are parsing.
+ /// The kind of template we are parsing.
enum {
- /// \brief We are not parsing a template at all.
+ /// We are not parsing a template at all.
NonTemplate = 0,
- /// \brief We are parsing a template declaration.
+ /// We are parsing a template declaration.
Template,
- /// \brief We are parsing an explicit specialization.
+ /// We are parsing an explicit specialization.
ExplicitSpecialization,
- /// \brief We are parsing an explicit instantiation.
+ /// We are parsing an explicit instantiation.
ExplicitInstantiation
} Kind;
- /// \brief The template parameter lists, for template declarations
+ /// The template parameter lists, for template declarations
/// and explicit specializations.
TemplateParameterLists *TemplateParams;
- /// \brief The location of the 'extern' keyword, if any, for an explicit
+ /// The location of the 'extern' keyword, if any, for an explicit
/// instantiation
SourceLocation ExternLoc;
- /// \brief The location of the 'template' keyword, for an explicit
+ /// The location of the 'template' keyword, for an explicit
/// instantiation.
SourceLocation TemplateLoc;
- /// \brief Whether the last template parameter list was empty.
+ /// Whether the last template parameter list was empty.
bool LastParameterListWasEmpty;
SourceRange getSourceRange() const LLVM_READONLY;
@@ -1267,11 +1361,11 @@ private:
};
NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS,
- AttributeList *AccessAttrs,
- ParsingDeclarator &D,
- const ParsedTemplateInfo &TemplateInfo,
- const VirtSpecifiers& VS,
- SourceLocation PureSpecLoc);
+ ParsedAttributes &AccessAttrs,
+ ParsingDeclarator &D,
+ const ParsedTemplateInfo &TemplateInfo,
+ const VirtSpecifiers &VS,
+ SourceLocation PureSpecLoc);
void ParseCXXNonStaticMemberInitializer(Decl *VarD);
void ParseLexedAttributes(ParsingClass &Class);
void ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
@@ -1312,6 +1406,15 @@ private:
SourceRange Range;
};
+ struct ParsedAttributesViewWithRange : ParsedAttributesView {
+ ParsedAttributesViewWithRange() : ParsedAttributesView() {}
+ void clearListOnly() {
+ ParsedAttributesView::clearListOnly();
+ Range = SourceRange();
+ }
+
+ SourceRange Range;
+ };
DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
ParsingDeclSpec *DS = nullptr);
@@ -1337,7 +1440,7 @@ private:
// Objective-C External Declarations
void MaybeSkipAttributes(tok::ObjCKeywordKind Kind);
- DeclGroupPtrTy ParseObjCAtDirectives();
+ DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs);
DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
ParsedAttributes &prefixAttrs);
@@ -1447,7 +1550,7 @@ private:
bool isTokIdentifier_in() const;
- ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, Declarator::TheContext Ctx,
+ ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, DeclaratorContext Ctx,
ParsedAttributes *ParamAttrs);
void ParseObjCMethodRequirement();
Decl *ParseObjCMethodPrototype(
@@ -1475,6 +1578,7 @@ public:
ExprResult ParseConstantExpressionInExprEvalContext(
TypeCastState isTypeCast = NotTypeCast);
ExprResult ParseConstantExpression(TypeCastState isTypeCast = NotTypeCast);
+ ExprResult ParseCaseExpression(SourceLocation CaseLoc);
ExprResult ParseConstraintExpression();
// Expr that doesn't include commas.
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast = NotTypeCast);
@@ -1513,6 +1617,14 @@ private:
}
bool diagnoseUnknownTemplateId(ExprResult TemplateName, SourceLocation Less);
+ void checkPotentialAngleBracket(ExprResult &PotentialTemplateName);
+ bool checkPotentialAngleBracketDelimiter(const AngleBracketTracker::Loc &,
+ const Token &OpToken);
+ bool checkPotentialAngleBracketDelimiter(const Token &OpToken) {
+ if (auto *Info = AngleBrackets.getCurrent(*this))
+ return checkPotentialAngleBracketDelimiter(*Info, OpToken);
+ return false;
+ }
ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
ExprResult ParseUnaryExprOrTypeTraitExpression();
@@ -1641,7 +1753,8 @@ private:
//===--------------------------------------------------------------------===//
// C++0x 8: Function declaration trailing-return-type
- TypeResult ParseTrailingReturnType(SourceRange &Range);
+ TypeResult ParseTrailingReturnType(SourceRange &Range,
+ bool MayBeFollowedByDirectInit);
//===--------------------------------------------------------------------===//
// C++ 2.13.5: C++ Boolean Literals
@@ -1737,11 +1850,11 @@ private:
StmtResult ParseStatement(SourceLocation *TrailingElseLoc = nullptr,
bool AllowOpenMPStandalone = false);
enum AllowedConstructsKind {
- /// \brief Allow any declarations, statements, OpenMP directives.
+ /// Allow any declarations, statements, OpenMP directives.
ACK_Any,
- /// \brief Allow only statements and non-standalone OpenMP directives.
+ /// Allow only statements and non-standalone OpenMP directives.
ACK_StatementsOpenMPNonStandalone,
- /// \brief Allow statements and all executable OpenMP directives
+ /// Allow statements and all executable OpenMP directives
ACK_StatementsOpenMPAnyExecutable
};
StmtResult
@@ -1782,34 +1895,34 @@ private:
SourceLocation *TrailingElseLoc,
ParsedAttributesWithRange &Attrs);
- /// \brief Describes the behavior that should be taken for an __if_exists
+ /// Describes the behavior that should be taken for an __if_exists
/// block.
enum IfExistsBehavior {
- /// \brief Parse the block; this code is always used.
+ /// Parse the block; this code is always used.
IEB_Parse,
- /// \brief Skip the block entirely; this code is never used.
+ /// Skip the block entirely; this code is never used.
IEB_Skip,
- /// \brief Parse the block as a dependent block, which may be used in
+ /// Parse the block as a dependent block, which may be used in
/// some template instantiations but not others.
IEB_Dependent
};
- /// \brief Describes the condition of a Microsoft __if_exists or
+ /// Describes the condition of a Microsoft __if_exists or
/// __if_not_exists block.
struct IfExistsCondition {
- /// \brief The location of the initial keyword.
+ /// The location of the initial keyword.
SourceLocation KeywordLoc;
- /// \brief Whether this is an __if_exists block (rather than an
+ /// Whether this is an __if_exists block (rather than an
/// __if_not_exists block).
bool IsIfExists;
- /// \brief Nested-name-specifier preceding the name.
+ /// Nested-name-specifier preceding the name.
CXXScopeSpec SS;
- /// \brief The name we're looking for.
+ /// The name we're looking for.
UnqualifiedId Name;
- /// \brief The behavior of this __if_exists or __if_not_exists block
+ /// The behavior of this __if_exists or __if_not_exists block
/// should.
IfExistsBehavior Behavior;
};
@@ -1818,7 +1931,8 @@ private:
void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
void ParseMicrosoftIfExistsExternalDeclaration();
void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
- AccessSpecifier& CurAS);
+ ParsedAttributes &AccessAttrs,
+ AccessSpecifier &CurAS);
bool ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
bool &InitExprsOk);
bool ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
@@ -1856,7 +1970,7 @@ private:
/// A context for parsing declaration specifiers. TODO: flesh this
/// out, there are other significant restrictions on specifiers than
/// would be best implemented in the parser.
- enum DeclSpecContext {
+ enum class DeclSpecContext {
DSC_normal, // normal context
DSC_class, // class context, enables 'friend'
DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
@@ -1873,18 +1987,18 @@ private:
/// trailing-type-specifier)?
static bool isTypeSpecifier(DeclSpecContext DSC) {
switch (DSC) {
- case DSC_normal:
- case DSC_template_param:
- case DSC_class:
- case DSC_top_level:
- case DSC_objc_method_result:
- case DSC_condition:
+ case DeclSpecContext::DSC_normal:
+ case DeclSpecContext::DSC_template_param:
+ case DeclSpecContext::DSC_class:
+ case DeclSpecContext::DSC_top_level:
+ case DeclSpecContext::DSC_objc_method_result:
+ case DeclSpecContext::DSC_condition:
return false;
- case DSC_template_type_arg:
- case DSC_type_specifier:
- case DSC_trailing:
- case DSC_alias_declaration:
+ case DeclSpecContext::DSC_template_type_arg:
+ case DeclSpecContext::DSC_type_specifier:
+ case DeclSpecContext::DSC_trailing:
+ case DeclSpecContext::DSC_alias_declaration:
return true;
}
llvm_unreachable("Missing DeclSpecContext case");
@@ -1894,18 +2008,18 @@ private:
/// deduction?
static bool isClassTemplateDeductionContext(DeclSpecContext DSC) {
switch (DSC) {
- case DSC_normal:
- case DSC_template_param:
- case DSC_class:
- case DSC_top_level:
- case DSC_condition:
- case DSC_type_specifier:
+ case DeclSpecContext::DSC_normal:
+ case DeclSpecContext::DSC_template_param:
+ case DeclSpecContext::DSC_class:
+ case DeclSpecContext::DSC_top_level:
+ case DeclSpecContext::DSC_condition:
+ case DeclSpecContext::DSC_type_specifier:
return true;
- case DSC_objc_method_result:
- case DSC_template_type_arg:
- case DSC_trailing:
- case DSC_alias_declaration:
+ case DeclSpecContext::DSC_objc_method_result:
+ case DeclSpecContext::DSC_template_type_arg:
+ case DeclSpecContext::DSC_trailing:
+ case DeclSpecContext::DSC_alias_declaration:
return false;
}
llvm_unreachable("Missing DeclSpecContext case");
@@ -1920,15 +2034,16 @@ private:
bool ParsedForRangeDecl() { return !ColonLoc.isInvalid(); }
};
- DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd,
+ DeclGroupPtrTy ParseDeclaration(DeclaratorContext Context,
+ SourceLocation &DeclEnd,
ParsedAttributesWithRange &attrs);
- DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
+ DeclGroupPtrTy ParseSimpleDeclaration(DeclaratorContext Context,
SourceLocation &DeclEnd,
ParsedAttributesWithRange &attrs,
bool RequireSemi,
ForRangeInit *FRI = nullptr);
- bool MightBeDeclarator(unsigned Context);
- DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
+ bool MightBeDeclarator(DeclaratorContext Context);
+ DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, DeclaratorContext Context,
SourceLocation *DeclEnd = nullptr,
ForRangeInit *FRI = nullptr);
Decl *ParseDeclarationAfterDeclarator(Declarator &D,
@@ -1941,7 +2056,7 @@ private:
Decl *ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope);
Decl *ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope);
- /// \brief When in code-completion, skip parsing of the function/method body
+ /// When in code-completion, skip parsing of the function/method body
/// unless the body contains the code-completion point.
///
/// \returns true if the function body was skipped.
@@ -1951,21 +2066,24 @@ private:
const ParsedTemplateInfo &TemplateInfo,
AccessSpecifier AS, DeclSpecContext DSC,
ParsedAttributesWithRange &Attrs);
- DeclSpecContext getDeclSpecContextFromDeclaratorContext(unsigned Context);
- void ParseDeclarationSpecifiers(DeclSpec &DS,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- AccessSpecifier AS = AS_none,
- DeclSpecContext DSC = DSC_normal,
- LateParsedAttrList *LateAttrs = nullptr);
- bool DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
- DeclSpecContext DSContext,
- LateParsedAttrList *LateAttrs = nullptr);
-
- void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none,
- DeclSpecContext DSC = DSC_normal);
+ DeclSpecContext
+ getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context);
+ void ParseDeclarationSpecifiers(
+ DeclSpec &DS,
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+ AccessSpecifier AS = AS_none,
+ DeclSpecContext DSC = DeclSpecContext::DSC_normal,
+ LateParsedAttrList *LateAttrs = nullptr);
+ bool DiagnoseMissingSemiAfterTagDefinition(
+ DeclSpec &DS, AccessSpecifier AS, DeclSpecContext DSContext,
+ LateParsedAttrList *LateAttrs = nullptr);
+
+ void ParseSpecifierQualifierList(
+ DeclSpec &DS, AccessSpecifier AS = AS_none,
+ DeclSpecContext DSC = DeclSpecContext::DSC_normal);
void ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
- Declarator::TheContext Context);
+ DeclaratorContext Context);
void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
const ParsedTemplateInfo &TemplateInfo,
@@ -1986,7 +2104,7 @@ private:
/// specifier or if we're not sure.
bool isKnownToBeTypeSpecifier(const Token &Tok) const;
- /// \brief Return true if we know that we are definitely looking at a
+ /// Return true if we know that we are definitely looking at a
/// decl-specifier, and isn't part of an expression such as a function-style
/// cast. Return false if it's no a decl-specifier, or we're not sure.
bool isKnownToBeDeclarationSpecifier() {
@@ -2014,19 +2132,19 @@ private:
return isDeclarationSpecifier(true);
}
- /// \brief Determine whether this is a C++1z for-range-identifier.
+ /// Determine whether this is a C++1z for-range-identifier.
bool isForRangeIdentifier();
- /// \brief Determine whether we are currently at the start of an Objective-C
+ /// Determine whether we are currently at the start of an Objective-C
/// class message that appears to be missing the open bracket '['.
bool isStartOfObjCClassMessageMissingOpenBracket();
- /// \brief Starting with a scope specifier, identifier, or
+ /// Starting with a scope specifier, identifier, or
/// template-id that refers to the current class, determine whether
/// this is a constructor declarator.
bool isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false);
- /// \brief Specifies the context in which type-id/expression
+ /// Specifies the context in which type-id/expression
/// disambiguation will occur.
enum TentativeCXXTypeIdContext {
TypeIdInParens,
@@ -2049,7 +2167,7 @@ private:
return isTypeIdInParens(isAmbiguous);
}
- /// \brief Checks if the current tokens form type-id or expression.
+ /// Checks if the current tokens form type-id or expression.
/// It is similar to isTypeIdInParens but does not suppose that type-id
/// is in parenthesis.
bool isTypeIdUnambiguously() {
@@ -2087,7 +2205,7 @@ private:
InitStmtDecl, ///< Disambiguated as a simple-declaration init-statement.
Error ///< Can't be any of the above!
};
- /// \brief Disambiguates between the different kinds of things that can happen
+ /// Disambiguates between the different kinds of things that can happen
/// after 'if (' or 'switch ('. This could be one of two different kinds of
/// declaration (depending on whether there is a ';' later) or an expression.
ConditionOrInitStatement
@@ -2105,7 +2223,7 @@ private:
True, False, Ambiguous, Error
};
- /// \brief Based only on the given token kind, determine whether we know that
+ /// Based only on the given token kind, determine whether we know that
/// we're at the start of an expression or a type-specifier-seq (which may
/// be an expression, in C++).
///
@@ -2133,7 +2251,7 @@ private:
/// a type-specifier other than a cv-qualifier.
bool isCXXDeclarationSpecifierAType();
- /// \brief Determine whether an identifier has been tentatively declared as a
+ /// Determine whether an identifier has been tentatively declared as a
/// non-type. Such tentative declarations should not be found to name a type
/// during a tentative parse, but also should not be annotated as a non-type.
bool isTentativelyDeclared(IdentifierInfo *II);
@@ -2151,7 +2269,8 @@ private:
TPResult TryParsePtrOperatorSeq();
TPResult TryParseOperatorId();
TPResult TryParseInitDeclaratorList();
- TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true);
+ TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier = true,
+ bool mayHaveDirectInit = false);
TPResult
TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = nullptr,
bool VersusTemplateArg = false);
@@ -2161,8 +2280,8 @@ private:
public:
TypeResult ParseTypeName(SourceRange *Range = nullptr,
- Declarator::TheContext Context
- = Declarator::TypeNameContext,
+ DeclaratorContext Context
+ = DeclaratorContext::TypeNameContext,
AccessSpecifier AS = AS_none,
Decl **OwnedType = nullptr,
ParsedAttributes *Attrs = nullptr);
@@ -2202,14 +2321,23 @@ private:
DeclSpec &DS, Sema::TagUseKind TUK);
// FixItLoc = possible correct location for the attributes
- void ProhibitAttributes(ParsedAttributesWithRange &attrs,
+ void ProhibitAttributes(ParsedAttributesWithRange &Attrs,
+ SourceLocation FixItLoc = SourceLocation()) {
+ if (Attrs.Range.isInvalid())
+ return;
+ DiagnoseProhibitedAttributes(Attrs.Range, FixItLoc);
+ Attrs.clear();
+ }
+
+ void ProhibitAttributes(ParsedAttributesViewWithRange &Attrs,
SourceLocation FixItLoc = SourceLocation()) {
- if (!attrs.Range.isValid()) return;
- DiagnoseProhibitedAttributes(attrs, FixItLoc);
- attrs.clear();
+ if (Attrs.Range.isInvalid())
+ return;
+ DiagnoseProhibitedAttributes(Attrs.Range, FixItLoc);
+ Attrs.clearListOnly();
}
- void DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs,
- SourceLocation FixItLoc);
+ void DiagnoseProhibitedAttributes(const SourceRange &Range,
+ SourceLocation FixItLoc);
// Forbid C++11 and C2x attributes that appear on certain syntactic locations
// which standard permits but we don't supported yet, for example, attributes
@@ -2217,16 +2345,16 @@ private:
void ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs,
unsigned DiagID);
- /// \brief Skip C++11 and C2x attributes and return the end location of the
+ /// Skip C++11 and C2x attributes and return the end location of the
/// last one.
/// \returns SourceLocation() if there are no attributes.
SourceLocation SkipCXX11Attributes();
- /// \brief Diagnose and skip C++11 and C2x attributes that appear in syntactic
+ /// Diagnose and skip C++11 and C2x attributes that appear in syntactic
/// locations where attributes are not allowed.
void DiagnoseAndSkipCXX11Attributes();
- /// \brief Parses syntax-generic attribute arguments for attributes which are
+ /// Parses syntax-generic attribute arguments for attributes which are
/// known to the implementation, and adds them to the given ParsedAttributes
/// list with the given attribute syntax. Returns the number of arguments
/// parsed for the attribute.
@@ -2234,7 +2362,7 @@ private:
ParseAttributeArgsCommon(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, SourceLocation *EndLoc,
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax);
+ ParsedAttr::Syntax Syntax);
void MaybeParseGNUAttributes(Declarator &D,
LateParsedAttrList *LateAttrs = nullptr) {
@@ -2257,19 +2385,16 @@ private:
Declarator *D = nullptr);
void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs,
- SourceLocation *EndLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax,
- Declarator *D);
+ ParsedAttributes &Attrs, SourceLocation *EndLoc,
+ IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+ ParsedAttr::Syntax Syntax, Declarator *D);
IdentifierLoc *ParseIdentifierLoc();
unsigned
ParseClangAttributeArgs(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, SourceLocation *EndLoc,
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax);
+ ParsedAttr::Syntax Syntax);
void MaybeParseCXX11Attributes(Declarator &D) {
if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) {
@@ -2299,7 +2424,7 @@ private:
SourceLocation *EndLoc = nullptr);
void ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
SourceLocation *EndLoc = nullptr);
- /// \brief Parses a C++11 (or C2x)-style attribute argument list. Returns true
+ /// Parses a C++11 (or C2x)-style attribute argument list. Returns true
/// if this results in adding an attribute to the ParsedAttributes list.
bool ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
SourceLocation AttrNameLoc,
@@ -2335,7 +2460,7 @@ private:
void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
void ParseOpenCLKernelAttributes(ParsedAttributes &attrs);
void ParseOpenCLQualifiers(ParsedAttributes &Attrs);
- /// \brief Parses opencl_unroll_hint attribute if language is OpenCL v2.0
+ /// Parses opencl_unroll_hint attribute if language is OpenCL v2.0
/// or higher.
/// \return false if error happens.
bool MaybeParseOpenCLUnrollHintAttribute(ParsedAttributes &Attrs) {
@@ -2343,7 +2468,7 @@ private:
return ParseOpenCLUnrollHintAttribute(Attrs);
return true;
}
- /// \brief Parses opencl_unroll_hint attribute.
+ /// Parses opencl_unroll_hint attribute.
/// \return false if error happens.
bool ParseOpenCLUnrollHintAttribute(ParsedAttributes &Attrs);
void ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs);
@@ -2355,7 +2480,7 @@ private:
SourceLocation *endLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax);
+ ParsedAttr::Syntax Syntax);
Optional<AvailabilitySpec> ParseAvailabilitySpec();
ExprResult ParseAvailabilityCheckExpr(SourceLocation StartLoc);
@@ -2366,7 +2491,7 @@ private:
SourceLocation *EndLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax);
+ ParsedAttr::Syntax Syntax);
void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
SourceLocation ObjCBridgeRelatedLoc,
@@ -2374,7 +2499,7 @@ private:
SourceLocation *endLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax);
+ ParsedAttr::Syntax Syntax);
void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
SourceLocation AttrNameLoc,
@@ -2382,15 +2507,13 @@ private:
SourceLocation *EndLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax);
+ ParsedAttr::Syntax Syntax);
- void ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
- SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs,
- SourceLocation *EndLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc,
- AttributeList::Syntax Syntax);
+ void
+ ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
+ SourceLocation AttrNameLoc, ParsedAttributes &Attrs,
+ SourceLocation *EndLoc, IdentifierInfo *ScopeName,
+ SourceLocation ScopeLoc, ParsedAttr::Syntax Syntax);
void ParseTypeofSpecifier(DeclSpec &DS);
SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
@@ -2512,20 +2635,21 @@ private:
void DiagnoseUnexpectedNamespace(NamedDecl *Context);
- DeclGroupPtrTy ParseNamespace(unsigned Context, SourceLocation &DeclEnd,
+ DeclGroupPtrTy ParseNamespace(DeclaratorContext Context,
+ SourceLocation &DeclEnd,
SourceLocation InlineLoc = SourceLocation());
- void ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc,
- std::vector<IdentifierInfo*>& Ident,
- std::vector<SourceLocation>& NamespaceLoc,
- unsigned int index, SourceLocation& InlineLoc,
- ParsedAttributes& attrs,
+ void ParseInnerNamespace(std::vector<SourceLocation> &IdentLoc,
+ std::vector<IdentifierInfo *> &Ident,
+ std::vector<SourceLocation> &NamespaceLoc,
+ unsigned int index, SourceLocation &InlineLoc,
+ ParsedAttributes &attrs,
BalancedDelimiterTracker &Tracker);
- Decl *ParseLinkage(ParsingDeclSpec &DS, unsigned Context);
+ Decl *ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context);
Decl *ParseExportDeclaration();
DeclGroupPtrTy ParseUsingDirectiveOrDeclaration(
- unsigned Context, const ParsedTemplateInfo &TemplateInfo,
+ DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
SourceLocation &DeclEnd, ParsedAttributesWithRange &attrs);
- Decl *ParseUsingDirective(unsigned Context,
+ Decl *ParseUsingDirective(DeclaratorContext Context,
SourceLocation UsingLoc,
SourceLocation &DeclEnd,
ParsedAttributes &attrs);
@@ -2533,19 +2657,18 @@ private:
struct UsingDeclarator {
SourceLocation TypenameLoc;
CXXScopeSpec SS;
- SourceLocation TemplateKWLoc;
UnqualifiedId Name;
SourceLocation EllipsisLoc;
void clear() {
- TypenameLoc = TemplateKWLoc = EllipsisLoc = SourceLocation();
+ TypenameLoc = EllipsisLoc = SourceLocation();
SS.clear();
Name.clear();
}
};
- bool ParseUsingDeclarator(unsigned Context, UsingDeclarator &D);
- DeclGroupPtrTy ParseUsingDeclaration(unsigned Context,
+ bool ParseUsingDeclarator(DeclaratorContext Context, UsingDeclarator &D);
+ DeclGroupPtrTy ParseUsingDeclaration(DeclaratorContext Context,
const ParsedTemplateInfo &TemplateInfo,
SourceLocation UsingLoc,
SourceLocation &DeclEnd,
@@ -2586,7 +2709,7 @@ private:
void MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(Declarator &D,
VirtSpecifiers &VS);
DeclGroupPtrTy ParseCXXClassMemberDeclaration(
- AccessSpecifier AS, AttributeList *Attr,
+ AccessSpecifier AS, ParsedAttributes &Attr,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
ParsingDeclRAIIObject *DiagsFromTParams = nullptr);
DeclGroupPtrTy ParseCXXClassMemberDeclarationWithPragmas(
@@ -2623,18 +2746,18 @@ private:
DeclGroupPtrTy ParseOMPDeclareSimdClauses(DeclGroupPtrTy Ptr,
CachedTokens &Toks,
SourceLocation Loc);
- /// \brief Parses declarative OpenMP directives.
+ /// Parses declarative OpenMP directives.
DeclGroupPtrTy ParseOpenMPDeclarativeDirectiveWithExtDecl(
AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
DeclSpec::TST TagType = DeclSpec::TST_unspecified,
Decl *TagDecl = nullptr);
- /// \brief Parse 'omp declare reduction' construct.
+ /// Parse 'omp declare reduction' construct.
DeclGroupPtrTy ParseOpenMPDeclareReductionDirective(AccessSpecifier AS);
/// Parses initializer for provided omp_priv declaration inside the reduction
/// initializer.
void ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm);
- /// \brief Parses simple list of variables.
+ /// Parses simple list of variables.
///
/// \param Kind Kind of the directive.
/// \param Callback Callback function to be called for the list elements.
@@ -2646,7 +2769,7 @@ private:
const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
Callback,
bool AllowScopeSpecifier);
- /// \brief Parses declarative or executable directive.
+ /// Parses declarative or executable directive.
///
/// \param Allowed ACK_Any, if any directives are allowed,
/// ACK_StatementsOpenMPAnyExecutable - if any executable directives are
@@ -2655,7 +2778,7 @@ private:
///
StmtResult
ParseOpenMPDeclarativeOrExecutableDirective(AllowedConstructsKind Allowed);
- /// \brief Parses clause of kind \a CKind for directive of a kind \a Kind.
+ /// Parses clause of kind \a CKind for directive of a kind \a Kind.
///
/// \param DKind Kind of current directive.
/// \param CKind Kind of current clause.
@@ -2664,33 +2787,45 @@ private:
///
OMPClause *ParseOpenMPClause(OpenMPDirectiveKind DKind,
OpenMPClauseKind CKind, bool FirstClause);
- /// \brief Parses clause with a single expression of a kind \a Kind.
+ /// Parses clause with a single expression of a kind \a Kind.
///
/// \param Kind Kind of current clause.
+ /// \param ParseOnly true to skip the clause's semantic actions and return
+ /// nullptr.
///
- OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind);
- /// \brief Parses simple clause of a kind \a Kind.
+ OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
+ bool ParseOnly);
+ /// Parses simple clause of a kind \a Kind.
///
/// \param Kind Kind of current clause.
+ /// \param ParseOnly true to skip the clause's semantic actions and return
+ /// nullptr.
///
- OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind);
- /// \brief Parses clause with a single expression and an additional argument
+ OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind, bool ParseOnly);
+ /// Parses clause with a single expression and an additional argument
/// of a kind \a Kind.
///
/// \param Kind Kind of current clause.
+ /// \param ParseOnly true to skip the clause's semantic actions and return
+ /// nullptr.
///
- OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind);
- /// \brief Parses clause without any additional arguments.
+ OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
+ bool ParseOnly);
+ /// Parses clause without any additional arguments.
///
/// \param Kind Kind of current clause.
+ /// \param ParseOnly true to skip the clause's semantic actions and return
+ /// nullptr.
///
- OMPClause *ParseOpenMPClause(OpenMPClauseKind Kind);
- /// \brief Parses clause with the list of variables of a kind \a Kind.
+ OMPClause *ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly = false);
+ /// Parses clause with the list of variables of a kind \a Kind.
///
/// \param Kind Kind of current clause.
+ /// \param ParseOnly true to skip the clause's semantic actions and return
+ /// nullptr.
///
OMPClause *ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
- OpenMPClauseKind Kind);
+ OpenMPClauseKind Kind, bool ParseOnly);
public:
/// Parses simple expression in parens for single-expression clauses of OpenMP
@@ -2702,6 +2837,7 @@ public:
struct OpenMPVarListDataTy {
Expr *TailExpr = nullptr;
SourceLocation ColonLoc;
+ SourceLocation RLoc;
CXXScopeSpec ReductionIdScopeSpec;
DeclarationNameInfo ReductionId;
OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
@@ -2721,7 +2857,7 @@ public:
bool AllowConstructorName,
bool AllowDeductionGuide,
ParsedType ObjectType,
- SourceLocation& TemplateKWLoc,
+ SourceLocation *TemplateKWLoc,
UnqualifiedId &Result);
private:
@@ -2729,21 +2865,18 @@ private:
// C++ 14: Templates [temp]
// C++ 14.1: Template Parameters [temp.param]
- Decl *ParseDeclarationStartingWithTemplate(unsigned Context,
- SourceLocation &DeclEnd,
- AccessSpecifier AS = AS_none,
- AttributeList *AccessAttrs = nullptr);
- Decl *ParseTemplateDeclarationOrSpecialization(unsigned Context,
+ Decl *ParseDeclarationStartingWithTemplate(DeclaratorContext Context,
+ SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs,
+ AccessSpecifier AS = AS_none);
+ Decl *ParseTemplateDeclarationOrSpecialization(DeclaratorContext Context,
SourceLocation &DeclEnd,
- AccessSpecifier AS,
- AttributeList *AccessAttrs);
+ ParsedAttributes &AccessAttrs,
+ AccessSpecifier AS);
Decl *ParseSingleDeclarationAfterTemplate(
- unsigned Context,
- const ParsedTemplateInfo &TemplateInfo,
- ParsingDeclRAIIObject &DiagsFromParams,
- SourceLocation &DeclEnd,
- AccessSpecifier AS=AS_none,
- AttributeList *AccessAttrs = nullptr);
+ DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
+ ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs, AccessSpecifier AS = AS_none);
bool ParseTemplateParameters(unsigned Depth,
SmallVectorImpl<NamedDecl *> &TemplateParams,
SourceLocation &LAngleLoc,
@@ -2782,10 +2915,11 @@ private:
bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
ParsedTemplateArgument ParseTemplateTemplateArgument();
ParsedTemplateArgument ParseTemplateArgument();
- Decl *ParseExplicitInstantiation(unsigned Context,
+ Decl *ParseExplicitInstantiation(DeclaratorContext Context,
SourceLocation ExternLoc,
SourceLocation TemplateLoc,
SourceLocation &DeclEnd,
+ ParsedAttributes &AccessAttrs,
AccessSpecifier AS = AS_none);
//===--------------------------------------------------------------------===//
diff --git a/include/clang/Parse/RAIIObjectsForParser.h b/include/clang/Parse/RAIIObjectsForParser.h
index 0422b038da656..f45d6434833ea 100644
--- a/include/clang/Parse/RAIIObjectsForParser.h
+++ b/include/clang/Parse/RAIIObjectsForParser.h
@@ -25,7 +25,7 @@ namespace clang {
// TODO: move ParsingClassDefinition here.
// TODO: move TentativeParsingAction here.
- /// \brief A RAII object used to temporarily suppress access-like
+ /// A RAII object used to temporarily suppress access-like
/// checking. Access-like checks are those associated with
/// controlling the use of a declaration, like C++ access control
/// errors and deprecation warnings. They are contextually
@@ -84,7 +84,7 @@ namespace clang {
}
};
- /// \brief RAII object used to inform the actions that we're
+ /// RAII object used to inform the actions that we're
/// currently parsing a declaration. This is active when parsing a
/// variable's initializer, but not when parsing the body of a
/// class or function definition.
@@ -202,7 +202,7 @@ namespace clang {
ParsingDeclRAIIObject ParsingRAII;
public:
- ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS, TheContext C)
+ ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS, DeclaratorContext C)
: Declarator(DS, C), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {
}
@@ -288,7 +288,7 @@ namespace clang {
}
};
- /// \brief RAII object that makes '>' behave either as an operator
+ /// RAII object that makes '>' behave either as an operator
/// or as the closing angle bracket for a template argument list.
class GreaterThanIsOperatorScope {
bool &GreaterThanIsOperator;
@@ -320,7 +320,7 @@ namespace clang {
}
};
- /// \brief RAII object that makes sure paren/bracket/brace count is correct
+ /// RAII object that makes sure paren/bracket/brace count is correct
/// after declaration/statement parsing, even when there's a parsing error.
class ParenBraceBracketBalancer {
Parser &P;
@@ -331,6 +331,7 @@ namespace clang {
BraceCount(p.BraceCount) { }
~ParenBraceBracketBalancer() {
+ P.AngleBrackets.clear(P);
P.ParenCount = ParenCount;
P.BracketCount = BracketCount;
P.BraceCount = BraceCount;
@@ -361,7 +362,7 @@ namespace clang {
}
};
- /// \brief RAII class that helps handle the parsing of an open/close delimiter
+ /// RAII class that helps handle the parsing of an open/close delimiter
/// pair, such as braces { ... } or parentheses ( ... ).
class BalancedDelimiterTracker : public GreaterThanIsOperatorScope {
Parser& P;
@@ -378,8 +379,6 @@ namespace clang {
}
}
- enum { MaxDepth = 256 };
-
bool diagnoseOverflow();
bool diagnoseMissingClose();
@@ -443,7 +442,7 @@ namespace clang {
void skipToEnd();
};
- /// \brief RAIIObject to destroy the contents of a SmallVector of
+ /// RAIIObject to destroy the contents of a SmallVector of
/// TemplateIdAnnotation pointers and clear the vector.
class DestroyTemplateIdAnnotationsRAIIObj {
SmallVectorImpl<TemplateIdAnnotation *> &Container;
diff --git a/include/clang/Rewrite/Core/DeltaTree.h b/include/clang/Rewrite/Core/DeltaTree.h
index fbffb38e377dd..f798e9fc41eb3 100644
--- a/include/clang/Rewrite/Core/DeltaTree.h
+++ b/include/clang/Rewrite/Core/DeltaTree.h
@@ -1,4 +1,4 @@
-//===--- DeltaTree.h - B-Tree for Rewrite Delta tracking --------*- C++ -*-===//
+//===- DeltaTree.h - B-Tree for Rewrite Delta tracking ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,8 +14,6 @@
#ifndef LLVM_CLANG_REWRITE_CORE_DELTATREE_H
#define LLVM_CLANG_REWRITE_CORE_DELTATREE_H
-#include "llvm/Support/Compiler.h"
-
namespace clang {
/// DeltaTree - a multiway search tree (BTree) structure with some fancy
@@ -27,12 +25,14 @@ namespace clang {
/// as well, without traversing the whole tree.
class DeltaTree {
void *Root; // "DeltaTreeNode *"
- void operator=(const DeltaTree &) = delete;
+
public:
DeltaTree();
// Note: Currently we only support copying when the RHS is empty.
DeltaTree(const DeltaTree &RHS);
+
+ DeltaTree &operator=(const DeltaTree &) = delete;
~DeltaTree();
/// getDeltaAt - Return the accumulated delta at the specified file offset.
@@ -45,6 +45,7 @@ namespace clang {
/// into the current DeltaTree at offset FileIndex.
void AddDelta(unsigned FileIndex, int Delta);
};
-} // end namespace clang
-#endif
+} // namespace clang
+
+#endif // LLVM_CLANG_REWRITE_CORE_DELTATREE_H
diff --git a/include/clang/Rewrite/Core/HTMLRewrite.h b/include/clang/Rewrite/Core/HTMLRewrite.h
index 1fd7c7a3f84e2..0f1f490d8305a 100644
--- a/include/clang/Rewrite/Core/HTMLRewrite.h
+++ b/include/clang/Rewrite/Core/HTMLRewrite.h
@@ -31,7 +31,8 @@ namespace html {
/// start/end tags are placed at the start/end of each line if the range is
/// multiline.
void HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E,
- const char *StartTag, const char *EndTag);
+ const char *StartTag, const char *EndTag,
+ bool IsTokenRange = true);
/// HighlightRange - Highlight a range in the source code with the specified
/// start/end tags. The Start/end of the range must be in the same file.
diff --git a/include/clang/Rewrite/Core/RewriteBuffer.h b/include/clang/Rewrite/Core/RewriteBuffer.h
index d69c69b81e482..c618298f5e82e 100644
--- a/include/clang/Rewrite/Core/RewriteBuffer.h
+++ b/include/clang/Rewrite/Core/RewriteBuffer.h
@@ -1,4 +1,4 @@
-//===--- RewriteBuffer.h - Buffer rewriting interface -----------*- C++ -*-===//
+//===- RewriteBuffer.h - Buffer rewriting interface -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,7 +16,6 @@
#include "llvm/ADT/StringRef.h"
namespace clang {
- class Rewriter;
/// RewriteBuffer - As code is rewritten, SourceBuffer's from the original
/// input with modifications get a new RewriteBuffer associated with them. The
@@ -26,12 +25,16 @@ namespace clang {
/// locations after the insertion point have to be mapped.
class RewriteBuffer {
friend class Rewriter;
+
/// Deltas - Keep track of all the deltas in the source code due to insertions
/// and deletions.
DeltaTree Deltas;
+
RewriteRope Buffer;
+
public:
- typedef RewriteRope::const_iterator iterator;
+ using iterator = RewriteRope::const_iterator;
+
iterator begin() const { return Buffer.begin(); }
iterator end() const { return Buffer.end(); }
unsigned size() const { return Buffer.size(); }
@@ -45,7 +48,7 @@ public:
Initialize(Input.begin(), Input.end());
}
- /// \brief Write to \p Stream the result of applying all changes to the
+ /// Write to \p Stream the result of applying all changes to the
/// original buffer.
/// Note that it isn't safe to use this function to overwrite memory mapped
/// files in-place (PR17960). Consider using a higher-level utility such as
@@ -61,7 +64,6 @@ public:
/// InsertText - Insert some text at the specified point, where the offset in
/// the buffer is specified relative to the original SourceBuffer. The
/// text is inserted after the specified location.
- ///
void InsertText(unsigned OrigOffset, StringRef Str,
bool InsertAfter = true);
@@ -87,8 +89,7 @@ public:
void ReplaceText(unsigned OrigOffset, unsigned OrigLength,
StringRef NewStr);
-private: // Methods only usable by Rewriter.
-
+private:
/// getMappedOffset - Given an offset into the original SourceBuffer that this
/// RewriteBuffer is based on, map it into the offset space of the
/// RewriteBuffer. If AfterInserts is true and if the OrigOffset indicates a
@@ -112,6 +113,6 @@ private: // Methods only usable by Rewriter.
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_REWRITE_CORE_REWRITEBUFFER_H
diff --git a/include/clang/Rewrite/Core/RewriteRope.h b/include/clang/Rewrite/Core/RewriteRope.h
index 50025544854a6..2a0e0a4a639b1 100644
--- a/include/clang/Rewrite/Core/RewriteRope.h
+++ b/include/clang/Rewrite/Core/RewriteRope.h
@@ -1,4 +1,4 @@
-//===--- RewriteRope.h - Rope specialized for rewriter ----------*- C++ -*-===//
+//===- RewriteRope.h - Rope specialized for rewriter ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,13 +16,13 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstddef>
-#include <cstring>
#include <iterator>
+#include <utility>
namespace clang {
+
//===--------------------------------------------------------------------===//
// RopeRefCountString Class
//===--------------------------------------------------------------------===//
@@ -58,11 +58,10 @@ namespace clang {
/// different offsets) which is a nice constant time operation.
struct RopePiece {
llvm::IntrusiveRefCntPtr<RopeRefCountString> StrData;
- unsigned StartOffs;
- unsigned EndOffs;
-
- RopePiece() : StrData(nullptr), StartOffs(0), EndOffs(0) {}
+ unsigned StartOffs = 0;
+ unsigned EndOffs = 0;
+ RopePiece() = default;
RopePiece(llvm::IntrusiveRefCntPtr<RopeRefCountString> Str, unsigned Start,
unsigned End)
: StrData(std::move(Str)), StartOffs(Start), EndOffs(End) {}
@@ -88,18 +87,18 @@ namespace clang {
class RopePieceBTreeIterator :
public std::iterator<std::forward_iterator_tag, const char, ptrdiff_t> {
/// CurNode - The current B+Tree node that we are inspecting.
- const void /*RopePieceBTreeLeaf*/ *CurNode;
+ const void /*RopePieceBTreeLeaf*/ *CurNode = nullptr;
+
/// CurPiece - The current RopePiece in the B+Tree node that we're
/// inspecting.
- const RopePiece *CurPiece;
+ const RopePiece *CurPiece = nullptr;
+
/// CurChar - The current byte in the RopePiece we are pointing to.
- unsigned CurChar;
+ unsigned CurChar = 0;
+
public:
- // begin iterator.
+ RopePieceBTreeIterator() = default;
RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
- // end iterator
- RopePieceBTreeIterator()
- : CurNode(nullptr), CurPiece(nullptr), CurChar(0) {}
char operator*() const {
return (*CurPiece)[CurChar];
@@ -119,7 +118,8 @@ namespace clang {
MoveToNextPiece();
return *this;
}
- inline RopePieceBTreeIterator operator++(int) { // Postincrement
+
+ RopePieceBTreeIterator operator++(int) { // Postincrement
RopePieceBTreeIterator tmp = *this; ++*this; return tmp;
}
@@ -136,13 +136,15 @@ namespace clang {
class RopePieceBTree {
void /*RopePieceBTreeNode*/ *Root;
- void operator=(const RopePieceBTree &) = delete;
+
public:
RopePieceBTree();
RopePieceBTree(const RopePieceBTree &RHS);
+ RopePieceBTree &operator=(const RopePieceBTree &) = delete;
~RopePieceBTree();
- typedef RopePieceBTreeIterator iterator;
+ using iterator = RopePieceBTreeIterator;
+
iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); }
unsigned size() const;
@@ -168,19 +170,18 @@ class RewriteRope {
/// We allocate space for string data out of a buffer of size AllocChunkSize.
/// This keeps track of how much space is left.
llvm::IntrusiveRefCntPtr<RopeRefCountString> AllocBuffer;
- unsigned AllocOffs;
enum { AllocChunkSize = 4080 };
+ unsigned AllocOffs = AllocChunkSize;
public:
- RewriteRope() : AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {}
- RewriteRope(const RewriteRope &RHS)
- : Chunks(RHS.Chunks), AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {
- }
+ RewriteRope() = default;
+ RewriteRope(const RewriteRope &RHS) : Chunks(RHS.Chunks) {}
+
+ using iterator = RopePieceBTree::iterator;
+ using const_iterator = RopePieceBTree::iterator;
- typedef RopePieceBTree::iterator iterator;
- typedef RopePieceBTree::iterator const_iterator;
iterator begin() const { return Chunks.begin(); }
- iterator end() const { return Chunks.end(); }
+ iterator end() const { return Chunks.end(); }
unsigned size() const { return Chunks.size(); }
void clear() {
@@ -209,6 +210,6 @@ private:
RopePiece MakeRopeString(const char *Start, const char *End);
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_REWRITE_CORE_REWRITEROPE_H
diff --git a/include/clang/Rewrite/Core/Rewriter.h b/include/clang/Rewrite/Core/Rewriter.h
index 800372ea557f6..107968a9fb436 100644
--- a/include/clang/Rewrite/Core/Rewriter.h
+++ b/include/clang/Rewrite/Core/Rewriter.h
@@ -1,4 +1,4 @@
-//===--- Rewriter.h - Code rewriting interface ------------------*- C++ -*-===//
+//===- Rewriter.h - Code rewriting interface --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,52 +15,55 @@
#ifndef LLVM_CLANG_REWRITE_CORE_REWRITER_H
#define LLVM_CLANG_REWRITE_CORE_REWRITER_H
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Rewrite/Core/RewriteBuffer.h"
-#include <cstring>
+#include "llvm/ADT/StringRef.h"
#include <map>
#include <string>
namespace clang {
- class LangOptions;
- class SourceManager;
+
+class LangOptions;
+class SourceManager;
/// Rewriter - This is the main interface to the rewrite buffers. Its primary
/// job is to dispatch high-level requests to the low-level RewriteBuffers that
/// are involved.
class Rewriter {
- SourceManager *SourceMgr;
- const LangOptions *LangOpts;
+ SourceManager *SourceMgr = nullptr;
+ const LangOptions *LangOpts = nullptr;
std::map<FileID, RewriteBuffer> RewriteBuffers;
+
public:
struct RewriteOptions {
- /// \brief Given a source range, true to include previous inserts at the
+ /// Given a source range, true to include previous inserts at the
/// beginning of the range as part of the range itself (true by default).
- bool IncludeInsertsAtBeginOfRange;
- /// \brief Given a source range, true to include previous inserts at the
+ bool IncludeInsertsAtBeginOfRange = true;
+
+ /// Given a source range, true to include previous inserts at the
/// end of the range as part of the range itself (true by default).
- bool IncludeInsertsAtEndOfRange;
- /// \brief If true and removing some text leaves a blank line
+ bool IncludeInsertsAtEndOfRange = true;
+
+ /// If true and removing some text leaves a blank line
/// also remove the empty line (false by default).
- bool RemoveLineIfEmpty;
+ bool RemoveLineIfEmpty = false;
- RewriteOptions()
- : IncludeInsertsAtBeginOfRange(true),
- IncludeInsertsAtEndOfRange(true),
- RemoveLineIfEmpty(false) { }
+ RewriteOptions() {}
};
- typedef std::map<FileID, RewriteBuffer>::iterator buffer_iterator;
- typedef std::map<FileID, RewriteBuffer>::const_iterator const_buffer_iterator;
+ using buffer_iterator = std::map<FileID, RewriteBuffer>::iterator;
+ using const_buffer_iterator = std::map<FileID, RewriteBuffer>::const_iterator;
+ explicit Rewriter() = default;
explicit Rewriter(SourceManager &SM, const LangOptions &LO)
- : SourceMgr(&SM), LangOpts(&LO) {}
- explicit Rewriter() : SourceMgr(nullptr), LangOpts(nullptr) {}
+ : SourceMgr(&SM), LangOpts(&LO) {}
void setSourceMgr(SourceManager &SM, const LangOptions &LO) {
SourceMgr = &SM;
LangOpts = &LO;
}
+
SourceManager &getSourceMgr() const { return *SourceMgr; }
const LangOptions &getLangOpts() const { return *LangOpts; }
@@ -82,7 +85,6 @@ public:
/// in different buffers, this returns an empty string.
///
/// Note that this method is not particularly efficient.
- ///
std::string getRewrittenText(SourceRange Range) const;
/// InsertText - Insert the specified string at the specified location in the
@@ -103,7 +105,7 @@ public:
return InsertText(Loc, Str);
}
- /// \brief Insert the specified string after the token in the
+ /// Insert the specified string after the token in the
/// specified location.
bool InsertTextAfterToken(SourceLocation Loc, StringRef Str);
@@ -120,13 +122,13 @@ public:
bool RemoveText(SourceLocation Start, unsigned Length,
RewriteOptions opts = RewriteOptions());
- /// \brief Remove the specified text region.
+ /// Remove the specified text region.
bool RemoveText(CharSourceRange range,
RewriteOptions opts = RewriteOptions()) {
return RemoveText(range.getBegin(), getRangeSize(range, opts), opts);
}
- /// \brief Remove the specified text region.
+ /// Remove the specified text region.
bool RemoveText(SourceRange range, RewriteOptions opts = RewriteOptions()) {
return RemoveText(range.getBegin(), getRangeSize(range, opts), opts);
}
@@ -149,7 +151,7 @@ public:
/// operation.
bool ReplaceText(SourceRange range, SourceRange replacementRange);
- /// \brief Increase indentation for the lines between the given source range.
+ /// Increase indentation for the lines between the given source range.
/// To determine what the indentation should be, 'parentIndent' is used
/// that should be at a source location with an indentation one degree
/// lower than the given range.
@@ -190,6 +192,6 @@ private:
unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const;
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_REWRITE_CORE_REWRITER_H
diff --git a/include/clang/Rewrite/Core/TokenRewriter.h b/include/clang/Rewrite/Core/TokenRewriter.h
index 0f71e81c313e7..ab2c2c8b0adb2 100644
--- a/include/clang/Rewrite/Core/TokenRewriter.h
+++ b/include/clang/Rewrite/Core/TokenRewriter.h
@@ -1,4 +1,4 @@
-//===--- TokenRewriter.h - Token-based Rewriter -----------------*- C++ -*-===//
+//===- TokenRewriter.h - Token-based Rewriter -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,13 +17,16 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/Token.h"
+#include <cassert>
#include <list>
#include <map>
#include <memory>
namespace clang {
- class LangOptions;
- class ScratchBuffer;
+
+class LangOptions;
+class ScratchBuffer;
+class SourceManager;
class TokenRewriter {
/// TokenList - This is the list of raw tokens that make up this file. Each
@@ -31,7 +34,7 @@ namespace clang {
std::list<Token> TokenList;
/// TokenRefTy - This is the type used to refer to a token in the TokenList.
- typedef std::list<Token>::iterator TokenRefTy;
+ using TokenRefTy = std::list<Token>::iterator;
/// TokenAtLoc - This map indicates which token exists at a specific
/// SourceLocation. Since each token has a unique SourceLocation, this is a
@@ -40,23 +43,24 @@ namespace clang {
std::map<SourceLocation, TokenRefTy> TokenAtLoc;
/// ScratchBuf - This is the buffer that we create scratch tokens from.
- ///
std::unique_ptr<ScratchBuffer> ScratchBuf;
- TokenRewriter(const TokenRewriter &) = delete;
- void operator=(const TokenRewriter &) = delete;
public:
/// TokenRewriter - This creates a TokenRewriter for the file with the
/// specified FileID.
TokenRewriter(FileID FID, SourceManager &SM, const LangOptions &LO);
+
+ TokenRewriter(const TokenRewriter &) = delete;
+ TokenRewriter &operator=(const TokenRewriter &) = delete;
~TokenRewriter();
- typedef std::list<Token>::const_iterator token_iterator;
+ using token_iterator = std::list<Token>::const_iterator;
+
token_iterator token_begin() const { return TokenList.begin(); }
token_iterator token_end() const { return TokenList.end(); }
-
token_iterator AddTokenBefore(token_iterator I, const char *Val);
+
token_iterator AddTokenAfter(token_iterator I, const char *Val) {
assert(I != token_end() && "Cannot insert after token_end()!");
return AddTokenBefore(++I, Val);
@@ -72,8 +76,6 @@ namespace clang {
TokenRefTy AddToken(const Token &T, TokenRefTy Where);
};
+} // namespace clang
-
-} // end namespace clang
-
-#endif
+#endif // LLVM_CLANG_REWRITE_CORE_TOKENREWRITER_H
diff --git a/include/clang/Rewrite/Frontend/FixItRewriter.h b/include/clang/Rewrite/Frontend/FixItRewriter.h
index 3b1b31e0cdee0..7456840bc5c16 100644
--- a/include/clang/Rewrite/Frontend/FixItRewriter.h
+++ b/include/clang/Rewrite/Frontend/FixItRewriter.h
@@ -1,4 +1,4 @@
-//===--- FixItRewriter.h - Fix-It Rewriter Diagnostic Client ----*- C++ -*-===//
+//===- FixItRewriter.h - Fix-It Rewriter Diagnostic Client ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,105 +12,108 @@
// then forwards any diagnostics to the adapted diagnostic client.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_REWRITE_FRONTEND_FIXITREWRITER_H
#define LLVM_CLANG_REWRITE_FRONTEND_FIXITREWRITER_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Edit/EditedSource.h"
#include "clang/Rewrite/Core/Rewriter.h"
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
namespace clang {
+class LangOptions;
class SourceManager;
-class FileEntry;
class FixItOptions {
public:
- FixItOptions() : InPlace(false), FixWhatYouCan(false),
- FixOnlyWarnings(false), Silent(false) { }
-
+ FixItOptions() = default;
virtual ~FixItOptions();
- /// \brief This file is about to be rewritten. Return the name of the file
+ /// This file is about to be rewritten. Return the name of the file
/// that is okay to write to.
///
/// \param fd out parameter for file descriptor. After the call it may be set
/// to an open file descriptor for the returned filename, or it will be -1
/// otherwise.
- ///
virtual std::string RewriteFilename(const std::string &Filename, int &fd) = 0;
/// True if files should be updated in place. RewriteFilename is only called
/// if this is false.
- bool InPlace;
+ bool InPlace = false;
- /// \brief Whether to abort fixing a file when not all errors could be fixed.
- bool FixWhatYouCan;
+ /// Whether to abort fixing a file when not all errors could be fixed.
+ bool FixWhatYouCan = false;
- /// \brief Whether to only fix warnings and not errors.
- bool FixOnlyWarnings;
+ /// Whether to only fix warnings and not errors.
+ bool FixOnlyWarnings = false;
- /// \brief If true, only pass the diagnostic to the actual diagnostic consumer
+ /// If true, only pass the diagnostic to the actual diagnostic consumer
/// if it is an error or a fixit was applied as part of the diagnostic.
/// It basically silences warnings without accompanying fixits.
- bool Silent;
+ bool Silent = false;
};
class FixItRewriter : public DiagnosticConsumer {
- /// \brief The diagnostics machinery.
+ /// The diagnostics machinery.
DiagnosticsEngine &Diags;
edit::EditedSource Editor;
- /// \brief The rewriter used to perform the various code
+ /// The rewriter used to perform the various code
/// modifications.
Rewriter Rewrite;
- /// \brief The diagnostic client that performs the actual formatting
+ /// The diagnostic client that performs the actual formatting
/// of error messages.
DiagnosticConsumer *Client;
std::unique_ptr<DiagnosticConsumer> Owner;
- /// \brief Turn an input path into an output path. NULL implies overwriting
+ /// Turn an input path into an output path. NULL implies overwriting
/// the original.
FixItOptions *FixItOpts;
- /// \brief The number of rewriter failures.
- unsigned NumFailures;
+ /// The number of rewriter failures.
+ unsigned NumFailures = 0;
- /// \brief Whether the previous diagnostic was not passed to the consumer.
- bool PrevDiagSilenced;
+ /// Whether the previous diagnostic was not passed to the consumer.
+ bool PrevDiagSilenced = false;
public:
- typedef Rewriter::buffer_iterator iterator;
-
- /// \brief Initialize a new fix-it rewriter.
+ /// Initialize a new fix-it rewriter.
FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
const LangOptions &LangOpts, FixItOptions *FixItOpts);
- /// \brief Destroy the fix-it rewriter.
+ /// Destroy the fix-it rewriter.
~FixItRewriter() override;
- /// \brief Check whether there are modifications for a given file.
+ /// Check whether there are modifications for a given file.
bool IsModified(FileID ID) const {
return Rewrite.getRewriteBufferFor(ID) != nullptr;
}
+ using iterator = Rewriter::buffer_iterator;
+
// Iteration over files with changes.
iterator buffer_begin() { return Rewrite.buffer_begin(); }
iterator buffer_end() { return Rewrite.buffer_end(); }
- /// \brief Write a single modified source file.
+ /// Write a single modified source file.
///
/// \returns true if there was an error, false otherwise.
bool WriteFixedFile(FileID ID, raw_ostream &OS);
- /// \brief Write the modified source files.
+ /// Write the modified source files.
///
/// \returns true if there was an error, false otherwise.
bool WriteFixedFiles(
- std::vector<std::pair<std::string, std::string> > *RewrittenFiles=nullptr);
+ std::vector<std::pair<std::string, std::string>> *RewrittenFiles = nullptr);
/// IncludeInDiagnosticCounts - This method (whose default implementation
/// returns true) indicates whether the diagnostics handled by this
@@ -123,10 +126,10 @@ public:
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const Diagnostic &Info) override;
- /// \brief Emit a diagnostic via the adapted diagnostic client.
+ /// Emit a diagnostic via the adapted diagnostic client.
void Diag(SourceLocation Loc, unsigned DiagID);
};
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_REWRITE_FRONTEND_FIXITREWRITER_H
diff --git a/include/clang/Rewrite/Frontend/FrontendActions.h b/include/clang/Rewrite/Frontend/FrontendActions.h
index 5f83ac16fedf6..40d2f4c22afe0 100644
--- a/include/clang/Rewrite/Frontend/FrontendActions.h
+++ b/include/clang/Rewrite/Frontend/FrontendActions.h
@@ -46,7 +46,7 @@ public:
~FixItAction() override;
};
-/// \brief Emits changes to temporary files and uses them for the original
+/// Emits changes to temporary files and uses them for the original
/// frontend action.
class FixItRecompile : public WrapperFrontendAction {
public:
diff --git a/include/clang/Sema/AnalysisBasedWarnings.h b/include/clang/Sema/AnalysisBasedWarnings.h
index 64dd2d36bef89..6e8d83974e5b7 100644
--- a/include/clang/Sema/AnalysisBasedWarnings.h
+++ b/include/clang/Sema/AnalysisBasedWarnings.h
@@ -54,34 +54,34 @@ private:
/// \name Statistics
/// @{
- /// \brief Number of function CFGs built and analyzed.
+ /// Number of function CFGs built and analyzed.
unsigned NumFunctionsAnalyzed;
- /// \brief Number of functions for which the CFG could not be successfully
+ /// Number of functions for which the CFG could not be successfully
/// built.
unsigned NumFunctionsWithBadCFGs;
- /// \brief Total number of blocks across all CFGs.
+ /// Total number of blocks across all CFGs.
unsigned NumCFGBlocks;
- /// \brief Largest number of CFG blocks for a single function analyzed.
+ /// Largest number of CFG blocks for a single function analyzed.
unsigned MaxCFGBlocksPerFunction;
- /// \brief Total number of CFGs with variables analyzed for uninitialized
+ /// Total number of CFGs with variables analyzed for uninitialized
/// uses.
unsigned NumUninitAnalysisFunctions;
- /// \brief Total number of variables analyzed for uninitialized uses.
+ /// Total number of variables analyzed for uninitialized uses.
unsigned NumUninitAnalysisVariables;
- /// \brief Max number of variables analyzed for uninitialized uses in a single
+ /// Max number of variables analyzed for uninitialized uses in a single
/// function.
unsigned MaxUninitAnalysisVariablesPerFunction;
- /// \brief Total number of block visits during uninitialized use analysis.
+ /// Total number of block visits during uninitialized use analysis.
unsigned NumUninitAnalysisBlockVisits;
- /// \brief Max number of block visits during uninitialized use analysis of
+ /// Max number of block visits during uninitialized use analysis of
/// a single function.
unsigned MaxUninitAnalysisBlockVisitsPerFunction;
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 5d280b5608e71..ede3ddf919931 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -1,4 +1,4 @@
-//===---- CodeCompleteConsumer.h - Code Completion Interface ----*- C++ -*-===//
+//===- CodeCompleteConsumer.h - Code Completion Interface -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,107 +10,141 @@
// This file defines the CodeCompleteConsumer class.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
#define LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
#include "clang-c/Index.h"
-#include "clang/AST/CanonicalType.h"
-#include "clang/AST/DeclBase.h"
#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Sema/CodeCompleteOptions.h"
#include "clang/Sema/DeclSpec.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/type_traits.h"
+#include <cassert>
+#include <memory>
#include <string>
#include <utility>
namespace clang {
+class ASTContext;
class Decl;
+class DeclContext;
+class FunctionDecl;
+class FunctionTemplateDecl;
+class IdentifierInfo;
+class LangOptions;
+class NamedDecl;
+class NestedNameSpecifier;
+class Preprocessor;
+class RawComment;
+class Sema;
+class UsingShadowDecl;
-/// \brief Default priority values for code-completion results based
+/// Default priority values for code-completion results based
/// on their kind.
enum {
- /// \brief Priority for the next initialization in a constructor initializer
+ /// Priority for the next initialization in a constructor initializer
/// list.
CCP_NextInitializer = 7,
- /// \brief Priority for an enumeration constant inside a switch whose
+
+ /// Priority for an enumeration constant inside a switch whose
/// condition is of the enumeration type.
CCP_EnumInCase = 7,
- /// \brief Priority for a send-to-super completion.
+
+ /// Priority for a send-to-super completion.
CCP_SuperCompletion = 20,
- /// \brief Priority for a declaration that is in the local scope.
+
+ /// Priority for a declaration that is in the local scope.
CCP_LocalDeclaration = 34,
- /// \brief Priority for a member declaration found from the current
+
+ /// Priority for a member declaration found from the current
/// method or member function.
CCP_MemberDeclaration = 35,
- /// \brief Priority for a language keyword (that isn't any of the other
+
+ /// Priority for a language keyword (that isn't any of the other
/// categories).
CCP_Keyword = 40,
- /// \brief Priority for a code pattern.
+
+ /// Priority for a code pattern.
CCP_CodePattern = 40,
- /// \brief Priority for a non-type declaration.
+
+ /// Priority for a non-type declaration.
CCP_Declaration = 50,
- /// \brief Priority for a type.
+
+ /// Priority for a type.
CCP_Type = CCP_Declaration,
- /// \brief Priority for a constant value (e.g., enumerator).
+
+ /// Priority for a constant value (e.g., enumerator).
CCP_Constant = 65,
- /// \brief Priority for a preprocessor macro.
+
+ /// Priority for a preprocessor macro.
CCP_Macro = 70,
- /// \brief Priority for a nested-name-specifier.
+
+ /// Priority for a nested-name-specifier.
CCP_NestedNameSpecifier = 75,
- /// \brief Priority for a result that isn't likely to be what the user wants,
+
+ /// Priority for a result that isn't likely to be what the user wants,
/// but is included for completeness.
CCP_Unlikely = 80,
- /// \brief Priority for the Objective-C "_cmd" implicit parameter.
+ /// Priority for the Objective-C "_cmd" implicit parameter.
CCP_ObjC_cmd = CCP_Unlikely
};
-/// \brief Priority value deltas that are added to code-completion results
+/// Priority value deltas that are added to code-completion results
/// based on the context of the result.
enum {
- /// \brief The result is in a base class.
+ /// The result is in a base class.
CCD_InBaseClass = 2,
- /// \brief The result is a C++ non-static member function whose qualifiers
+
+ /// The result is a C++ non-static member function whose qualifiers
/// exactly match the object type on which the member function can be called.
CCD_ObjectQualifierMatch = -1,
- /// \brief The selector of the given message exactly matches the selector
+
+ /// The selector of the given message exactly matches the selector
/// of the current method, which might imply that some kind of delegation
/// is occurring.
CCD_SelectorMatch = -3,
- /// \brief Adjustment to the "bool" type in Objective-C, where the typedef
+ /// Adjustment to the "bool" type in Objective-C, where the typedef
/// "BOOL" is preferred.
CCD_bool_in_ObjC = 1,
- /// \brief Adjustment for KVC code pattern priorities when it doesn't look
+ /// Adjustment for KVC code pattern priorities when it doesn't look
/// like the
CCD_ProbablyNotObjCCollection = 15,
- /// \brief An Objective-C method being used as a property.
+ /// An Objective-C method being used as a property.
CCD_MethodAsProperty = 2,
- /// \brief An Objective-C block property completed as a setter with a
+ /// An Objective-C block property completed as a setter with a
/// block placeholder.
CCD_BlockPropertySetter = 3
};
-/// \brief Priority value factors by which we will divide or multiply the
+/// Priority value factors by which we will divide or multiply the
/// priority of a code-completion result.
enum {
- /// \brief Divide by this factor when a code-completion result's type exactly
+ /// Divide by this factor when a code-completion result's type exactly
/// matches the type we expect.
CCF_ExactTypeMatch = 4,
- /// \brief Divide by this factor when a code-completion result's type is
+
+ /// Divide by this factor when a code-completion result's type is
/// similar to the type we expect (e.g., both arithmetic types, both
/// Objective-C object pointer types).
CCF_SimilarTypeMatch = 2
};
-/// \brief A simplified classification of types used when determining
+/// A simplified classification of types used when determining
/// "similar" types for code completion.
enum SimplifiedTypeClass {
STC_Arithmetic,
@@ -124,14 +158,14 @@ enum SimplifiedTypeClass {
STC_Void
};
-/// \brief Determine the simplified type class of the given canonical type.
+/// Determine the simplified type class of the given canonical type.
SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T);
-/// \brief Determine the type that this declaration will have if it is used
+/// Determine the type that this declaration will have if it is used
/// as a type or in an expression.
QualType getDeclUsageType(ASTContext &C, const NamedDecl *ND);
-/// \brief Determine the priority to be given to a macro code completion result
+/// Determine the priority to be given to a macro code completion result
/// with the given name.
///
/// \param MacroName The name of the macro.
@@ -144,190 +178,230 @@ unsigned getMacroUsagePriority(StringRef MacroName,
const LangOptions &LangOpts,
bool PreferredTypeIsPointer = false);
-/// \brief Determine the libclang cursor kind associated with the given
+/// Determine the libclang cursor kind associated with the given
/// declaration.
CXCursorKind getCursorKindForDecl(const Decl *D);
-class FunctionDecl;
-class FunctionType;
-class FunctionTemplateDecl;
-class IdentifierInfo;
-class NamedDecl;
-class NestedNameSpecifier;
-class Sema;
-
-/// \brief The context in which code completion occurred, so that the
+/// The context in which code completion occurred, so that the
/// code-completion consumer can process the results accordingly.
class CodeCompletionContext {
public:
enum Kind {
- /// \brief An unspecified code-completion context.
+ /// An unspecified code-completion context.
CCC_Other,
- /// \brief An unspecified code-completion context where we should also add
+
+ /// An unspecified code-completion context where we should also add
/// macro completions.
CCC_OtherWithMacros,
- /// \brief Code completion occurred within a "top-level" completion context,
+
+ /// Code completion occurred within a "top-level" completion context,
/// e.g., at namespace or global scope.
CCC_TopLevel,
- /// \brief Code completion occurred within an Objective-C interface,
+
+ /// Code completion occurred within an Objective-C interface,
/// protocol, or category interface.
CCC_ObjCInterface,
- /// \brief Code completion occurred within an Objective-C implementation
+
+ /// Code completion occurred within an Objective-C implementation
/// or category implementation.
CCC_ObjCImplementation,
- /// \brief Code completion occurred within the instance variable list of
+
+ /// Code completion occurred within the instance variable list of
/// an Objective-C interface, implementation, or category implementation.
CCC_ObjCIvarList,
- /// \brief Code completion occurred within a class, struct, or union.
+
+ /// Code completion occurred within a class, struct, or union.
CCC_ClassStructUnion,
- /// \brief Code completion occurred where a statement (or declaration) is
+
+ /// Code completion occurred where a statement (or declaration) is
/// expected in a function, method, or block.
CCC_Statement,
- /// \brief Code completion occurred where an expression is expected.
+
+ /// Code completion occurred where an expression is expected.
CCC_Expression,
- /// \brief Code completion occurred where an Objective-C message receiver
+
+ /// Code completion occurred where an Objective-C message receiver
/// is expected.
CCC_ObjCMessageReceiver,
- /// \brief Code completion occurred on the right-hand side of a member
+
+ /// Code completion occurred on the right-hand side of a member
/// access expression using the dot operator.
///
/// The results of this completion are the members of the type being
/// accessed. The type itself is available via
/// \c CodeCompletionContext::getType().
CCC_DotMemberAccess,
- /// \brief Code completion occurred on the right-hand side of a member
+
+ /// Code completion occurred on the right-hand side of a member
/// access expression using the arrow operator.
///
/// The results of this completion are the members of the type being
/// accessed. The type itself is available via
/// \c CodeCompletionContext::getType().
CCC_ArrowMemberAccess,
- /// \brief Code completion occurred on the right-hand side of an Objective-C
+
+ /// Code completion occurred on the right-hand side of an Objective-C
/// property access expression.
///
/// The results of this completion are the members of the type being
/// accessed. The type itself is available via
/// \c CodeCompletionContext::getType().
CCC_ObjCPropertyAccess,
- /// \brief Code completion occurred after the "enum" keyword, to indicate
+
+ /// Code completion occurred after the "enum" keyword, to indicate
/// an enumeration name.
CCC_EnumTag,
- /// \brief Code completion occurred after the "union" keyword, to indicate
+
+ /// Code completion occurred after the "union" keyword, to indicate
/// a union name.
CCC_UnionTag,
- /// \brief Code completion occurred after the "struct" or "class" keyword,
+
+ /// Code completion occurred after the "struct" or "class" keyword,
/// to indicate a struct or class name.
CCC_ClassOrStructTag,
- /// \brief Code completion occurred where a protocol name is expected.
+
+ /// Code completion occurred where a protocol name is expected.
CCC_ObjCProtocolName,
- /// \brief Code completion occurred where a namespace or namespace alias
+
+ /// Code completion occurred where a namespace or namespace alias
/// is expected.
CCC_Namespace,
- /// \brief Code completion occurred where a type name is expected.
+
+ /// Code completion occurred where a type name is expected.
CCC_Type,
- /// \brief Code completion occurred where a new name is expected.
+
+ /// Code completion occurred where a new name is expected.
CCC_Name,
- /// \brief Code completion occurred where a new name is expected and a
+
+ /// Code completion occurred where a new name is expected and a
/// qualified name is permissible.
CCC_PotentiallyQualifiedName,
- /// \brief Code completion occurred where an macro is being defined.
+
+ /// Code completion occurred where an macro is being defined.
CCC_MacroName,
- /// \brief Code completion occurred where a macro name is expected
+
+ /// Code completion occurred where a macro name is expected
/// (without any arguments, in the case of a function-like macro).
CCC_MacroNameUse,
- /// \brief Code completion occurred within a preprocessor expression.
+
+ /// Code completion occurred within a preprocessor expression.
CCC_PreprocessorExpression,
- /// \brief Code completion occurred where a preprocessor directive is
+
+ /// Code completion occurred where a preprocessor directive is
/// expected.
CCC_PreprocessorDirective,
- /// \brief Code completion occurred in a context where natural language is
+
+ /// Code completion occurred in a context where natural language is
/// expected, e.g., a comment or string literal.
///
/// This context usually implies that no completions should be added,
/// unless they come from an appropriate natural-language dictionary.
CCC_NaturalLanguage,
- /// \brief Code completion for a selector, as in an \@selector expression.
+
+ /// Code completion for a selector, as in an \@selector expression.
CCC_SelectorName,
- /// \brief Code completion within a type-qualifier list.
+
+ /// Code completion within a type-qualifier list.
CCC_TypeQualifiers,
- /// \brief Code completion in a parenthesized expression, which means that
+
+ /// Code completion in a parenthesized expression, which means that
/// we may also have types here in C and Objective-C (as well as in C++).
CCC_ParenthesizedExpression,
- /// \brief Code completion where an Objective-C instance message is
+
+ /// Code completion where an Objective-C instance message is
/// expected.
CCC_ObjCInstanceMessage,
- /// \brief Code completion where an Objective-C class message is expected.
+
+ /// Code completion where an Objective-C class message is expected.
CCC_ObjCClassMessage,
- /// \brief Code completion where the name of an Objective-C class is
+
+ /// Code completion where the name of an Objective-C class is
/// expected.
CCC_ObjCInterfaceName,
- /// \brief Code completion where an Objective-C category name is expected.
+
+ /// Code completion where an Objective-C category name is expected.
CCC_ObjCCategoryName,
- /// \brief An unknown context, in which we are recovering from a parsing
+
+ /// An unknown context, in which we are recovering from a parsing
/// error and don't know which completions we should give.
CCC_Recovery
};
+ using VisitedContextSet = llvm::SmallPtrSet<DeclContext *, 8>;
+
private:
- enum Kind Kind;
+ Kind CCKind;
- /// \brief The type that would prefer to see at this point (e.g., the type
+ /// The type that would prefer to see at this point (e.g., the type
/// of an initializer or function parameter).
QualType PreferredType;
- /// \brief The type of the base object in a member access expression.
+ /// The type of the base object in a member access expression.
QualType BaseType;
- /// \brief The identifiers for Objective-C selector parts.
+ /// The identifiers for Objective-C selector parts.
ArrayRef<IdentifierInfo *> SelIdents;
- /// \brief The scope specifier that comes before the completion token e.g.
+ /// The scope specifier that comes before the completion token e.g.
/// "a::b::"
llvm::Optional<CXXScopeSpec> ScopeSpecifier;
+ /// A set of declaration contexts visited by Sema when doing lookup for
+ /// code completion.
+ VisitedContextSet VisitedContexts;
+
public:
- /// \brief Construct a new code-completion context of the given kind.
- CodeCompletionContext(enum Kind Kind) : Kind(Kind), SelIdents(None) { }
+ /// Construct a new code-completion context of the given kind.
+ CodeCompletionContext(Kind CCKind) : CCKind(CCKind), SelIdents(None) {}
- /// \brief Construct a new code-completion context of the given kind.
- CodeCompletionContext(enum Kind Kind, QualType T,
+ /// Construct a new code-completion context of the given kind.
+ CodeCompletionContext(Kind CCKind, QualType T,
ArrayRef<IdentifierInfo *> SelIdents = None)
- : Kind(Kind),
- SelIdents(SelIdents) {
- if (Kind == CCC_DotMemberAccess || Kind == CCC_ArrowMemberAccess ||
- Kind == CCC_ObjCPropertyAccess || Kind == CCC_ObjCClassMessage ||
- Kind == CCC_ObjCInstanceMessage)
+ : CCKind(CCKind), SelIdents(SelIdents) {
+ if (CCKind == CCC_DotMemberAccess || CCKind == CCC_ArrowMemberAccess ||
+ CCKind == CCC_ObjCPropertyAccess || CCKind == CCC_ObjCClassMessage ||
+ CCKind == CCC_ObjCInstanceMessage)
BaseType = T;
else
PreferredType = T;
}
- /// \brief Retrieve the kind of code-completion context.
- enum Kind getKind() const { return Kind; }
+ /// Retrieve the kind of code-completion context.
+ Kind getKind() const { return CCKind; }
- /// \brief Retrieve the type that this expression would prefer to have, e.g.,
+ /// Retrieve the type that this expression would prefer to have, e.g.,
/// if the expression is a variable initializer or a function argument, the
/// type of the corresponding variable or function parameter.
QualType getPreferredType() const { return PreferredType; }
- /// \brief Retrieve the type of the base object in a member-access
+ /// Retrieve the type of the base object in a member-access
/// expression.
QualType getBaseType() const { return BaseType; }
- /// \brief Retrieve the Objective-C selector identifiers.
+ /// Retrieve the Objective-C selector identifiers.
ArrayRef<IdentifierInfo *> getSelIdents() const { return SelIdents; }
- /// \brief Determines whether we want C++ constructors as results within this
+ /// Determines whether we want C++ constructors as results within this
/// context.
bool wantConstructorResults() const;
- /// \brief Sets the scope specifier that comes before the completion token.
+ /// Sets the scope specifier that comes before the completion token.
/// This is expected to be set in code completions on qualfied specifiers
/// (e.g. "a::b::").
void setCXXScopeSpecifier(CXXScopeSpec SS) {
this->ScopeSpecifier = std::move(SS);
}
+ /// Adds a visited context.
+ void addVisitedContext(DeclContext *Ctx) {
+ VisitedContexts.insert(Ctx);
+ }
+
+ /// Retrieves all visited contexts.
+ const VisitedContextSet &getVisitedContexts() const {
+ return VisitedContexts;
+ }
+
llvm::Optional<const CXXScopeSpec *> getCXXScopeSpecifier() {
if (ScopeSpecifier)
return ScopeSpecifier.getPointer();
@@ -335,7 +409,10 @@ public:
}
};
-/// \brief A "string" used to describe how code completion can
+/// Get string representation of \p Kind, useful for for debugging.
+llvm::StringRef getCompletionKindString(CodeCompletionContext::Kind Kind);
+
+/// A "string" used to describe how code completion can
/// be performed for an entity.
///
/// A code completion string typically shows how a particular entity can be
@@ -344,128 +421,147 @@ public:
/// arguments, etc.
class CodeCompletionString {
public:
- /// \brief The different kinds of "chunks" that can occur within a code
+ /// The different kinds of "chunks" that can occur within a code
/// completion string.
enum ChunkKind {
- /// \brief The piece of text that the user is expected to type to
+ /// The piece of text that the user is expected to type to
/// match the code-completion string, typically a keyword or the name of a
/// declarator or macro.
CK_TypedText,
- /// \brief A piece of text that should be placed in the buffer, e.g.,
+
+ /// A piece of text that should be placed in the buffer, e.g.,
/// parentheses or a comma in a function call.
CK_Text,
- /// \brief A code completion string that is entirely optional. For example,
+
+ /// A code completion string that is entirely optional. For example,
/// an optional code completion string that describes the default arguments
/// in a function call.
CK_Optional,
- /// \brief A string that acts as a placeholder for, e.g., a function
+
+ /// A string that acts as a placeholder for, e.g., a function
/// call argument.
CK_Placeholder,
- /// \brief A piece of text that describes something about the result but
+
+ /// A piece of text that describes something about the result but
/// should not be inserted into the buffer.
CK_Informative,
- /// \brief A piece of text that describes the type of an entity or, for
+ /// A piece of text that describes the type of an entity or, for
/// functions and methods, the return type.
CK_ResultType,
- /// \brief A piece of text that describes the parameter that corresponds
+
+ /// A piece of text that describes the parameter that corresponds
/// to the code-completion location within a function call, message send,
/// macro invocation, etc.
CK_CurrentParameter,
- /// \brief A left parenthesis ('(').
+
+ /// A left parenthesis ('(').
CK_LeftParen,
- /// \brief A right parenthesis (')').
+
+ /// A right parenthesis (')').
CK_RightParen,
- /// \brief A left bracket ('[').
+
+ /// A left bracket ('[').
CK_LeftBracket,
- /// \brief A right bracket (']').
+
+ /// A right bracket (']').
CK_RightBracket,
- /// \brief A left brace ('{').
+
+ /// A left brace ('{').
CK_LeftBrace,
- /// \brief A right brace ('}').
+
+ /// A right brace ('}').
CK_RightBrace,
- /// \brief A left angle bracket ('<').
+
+ /// A left angle bracket ('<').
CK_LeftAngle,
- /// \brief A right angle bracket ('>').
+
+ /// A right angle bracket ('>').
CK_RightAngle,
- /// \brief A comma separator (',').
+
+ /// A comma separator (',').
CK_Comma,
- /// \brief A colon (':').
+
+ /// A colon (':').
CK_Colon,
- /// \brief A semicolon (';').
+
+ /// A semicolon (';').
CK_SemiColon,
- /// \brief An '=' sign.
+
+ /// An '=' sign.
CK_Equal,
- /// \brief Horizontal whitespace (' ').
+
+ /// Horizontal whitespace (' ').
CK_HorizontalSpace,
- /// \brief Vertical whitespace ('\\n' or '\\r\\n', depending on the
+
+ /// Vertical whitespace ('\\n' or '\\r\\n', depending on the
/// platform).
CK_VerticalSpace
};
- /// \brief One piece of the code completion string.
+ /// One piece of the code completion string.
struct Chunk {
- /// \brief The kind of data stored in this piece of the code completion
+ /// The kind of data stored in this piece of the code completion
/// string.
- ChunkKind Kind;
+ ChunkKind Kind = CK_Text;
union {
- /// \brief The text string associated with a CK_Text, CK_Placeholder,
+ /// The text string associated with a CK_Text, CK_Placeholder,
/// CK_Informative, or CK_Comma chunk.
/// The string is owned by the chunk and will be deallocated
/// (with delete[]) when the chunk is destroyed.
const char *Text;
- /// \brief The code completion string associated with a CK_Optional chunk.
+ /// The code completion string associated with a CK_Optional chunk.
/// The optional code completion string is owned by the chunk, and will
/// be deallocated (with delete) when the chunk is destroyed.
CodeCompletionString *Optional;
};
- Chunk() : Kind(CK_Text), Text(nullptr) { }
+ Chunk() : Text(nullptr) {}
explicit Chunk(ChunkKind Kind, const char *Text = "");
- /// \brief Create a new text chunk.
+ /// Create a new text chunk.
static Chunk CreateText(const char *Text);
- /// \brief Create a new optional chunk.
+ /// Create a new optional chunk.
static Chunk CreateOptional(CodeCompletionString *Optional);
- /// \brief Create a new placeholder chunk.
+ /// Create a new placeholder chunk.
static Chunk CreatePlaceholder(const char *Placeholder);
- /// \brief Create a new informative chunk.
+ /// Create a new informative chunk.
static Chunk CreateInformative(const char *Informative);
- /// \brief Create a new result type chunk.
+ /// Create a new result type chunk.
static Chunk CreateResultType(const char *ResultType);
- /// \brief Create a new current-parameter chunk.
+ /// Create a new current-parameter chunk.
static Chunk CreateCurrentParameter(const char *CurrentParameter);
};
private:
- /// \brief The number of chunks stored in this string.
+ friend class CodeCompletionBuilder;
+ friend class CodeCompletionResult;
+
+ /// The number of chunks stored in this string.
unsigned NumChunks : 16;
- /// \brief The number of annotations for this code-completion result.
+ /// The number of annotations for this code-completion result.
unsigned NumAnnotations : 16;
- /// \brief The priority of this code-completion string.
+ /// The priority of this code-completion string.
unsigned Priority : 16;
- /// \brief The availability of this code-completion result.
+ /// The availability of this code-completion result.
unsigned Availability : 2;
-
- /// \brief The name of the parent context.
+
+ /// The name of the parent context.
StringRef ParentName;
- /// \brief A brief documentation comment attached to the declaration of
+ /// A brief documentation comment attached to the declaration of
/// entity being completed by this result.
const char *BriefComment;
-
- CodeCompletionString(const CodeCompletionString &) = delete;
- void operator=(const CodeCompletionString &) = delete;
CodeCompletionString(const Chunk *Chunks, unsigned NumChunks,
unsigned Priority, CXAvailabilityKind Availability,
@@ -474,11 +570,12 @@ private:
const char *BriefComment);
~CodeCompletionString() = default;
- friend class CodeCompletionBuilder;
- friend class CodeCompletionResult;
-
public:
- typedef const Chunk *iterator;
+ CodeCompletionString(const CodeCompletionString &) = delete;
+ CodeCompletionString &operator=(const CodeCompletionString &) = delete;
+
+ using iterator = const Chunk *;
+
iterator begin() const { return reinterpret_cast<const Chunk *>(this + 1); }
iterator end() const { return begin() + NumChunks; }
bool empty() const { return NumChunks == 0; }
@@ -489,22 +586,22 @@ public:
return begin()[I];
}
- /// \brief Returns the text in the TypedText chunk.
+ /// Returns the text in the TypedText chunk.
const char *getTypedText() const;
- /// \brief Retrieve the priority of this code completion result.
+ /// Retrieve the priority of this code completion result.
unsigned getPriority() const { return Priority; }
- /// \brief Retrieve the availability of this code completion result.
+ /// Retrieve the availability of this code completion result.
unsigned getAvailability() const { return Availability; }
- /// \brief Retrieve the number of annotations for this code completion result.
+ /// Retrieve the number of annotations for this code completion result.
unsigned getAnnotationCount() const;
- /// \brief Retrieve the annotation string specified by \c AnnotationNr.
+ /// Retrieve the annotation string specified by \c AnnotationNr.
const char *getAnnotation(unsigned AnnotationNr) const;
-
- /// \brief Retrieve the name of the parent context.
+
+ /// Retrieve the name of the parent context.
StringRef getParentContextName() const {
return ParentName;
}
@@ -512,20 +609,20 @@ public:
const char *getBriefComment() const {
return BriefComment;
}
-
- /// \brief Retrieve a string representation of the code completion string,
+
+ /// Retrieve a string representation of the code completion string,
/// which is mainly useful for debugging.
std::string getAsString() const;
};
-/// \brief An allocator used specifically for the purpose of code completion.
+/// An allocator used specifically for the purpose of code completion.
class CodeCompletionAllocator : public llvm::BumpPtrAllocator {
public:
- /// \brief Copy the given string into this allocator.
+ /// Copy the given string into this allocator.
const char *CopyString(const Twine &String);
};
-/// \brief Allocator for a cached set of global code completions.
+/// Allocator for a cached set of global code completions.
class GlobalCodeCompletionAllocator : public CodeCompletionAllocator {};
class CodeCompletionTUInfo {
@@ -540,6 +637,7 @@ public:
std::shared_ptr<GlobalCodeCompletionAllocator> getAllocatorRef() const {
return AllocatorRef;
}
+
CodeCompletionAllocator &getAllocator() const {
assert(AllocatorRef);
return *AllocatorRef;
@@ -548,30 +646,32 @@ public:
StringRef getParentName(const DeclContext *DC);
};
-} // end namespace clang
+} // namespace clang
namespace llvm {
- template <> struct isPodLike<clang::CodeCompletionString::Chunk> {
- static const bool value = true;
- };
-}
+
+template <> struct isPodLike<clang::CodeCompletionString::Chunk> {
+ static const bool value = true;
+};
+
+} // namespace llvm
namespace clang {
-/// \brief A builder class used to construct new code-completion strings.
+/// A builder class used to construct new code-completion strings.
class CodeCompletionBuilder {
public:
- typedef CodeCompletionString::Chunk Chunk;
+ using Chunk = CodeCompletionString::Chunk;
private:
CodeCompletionAllocator &Allocator;
CodeCompletionTUInfo &CCTUInfo;
- unsigned Priority;
- CXAvailabilityKind Availability;
+ unsigned Priority = 0;
+ CXAvailabilityKind Availability = CXAvailability_Available;
StringRef ParentName;
- const char *BriefComment;
-
- /// \brief The chunks stored in this string.
+ const char *BriefComment = nullptr;
+
+ /// The chunks stored in this string.
SmallVector<Chunk, 4> Chunks;
SmallVector<const char *, 2> Annotations;
@@ -579,203 +679,237 @@ private:
public:
CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
CodeCompletionTUInfo &CCTUInfo)
- : Allocator(Allocator), CCTUInfo(CCTUInfo),
- Priority(0), Availability(CXAvailability_Available),
- BriefComment(nullptr) { }
+ : Allocator(Allocator), CCTUInfo(CCTUInfo) {}
CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
CodeCompletionTUInfo &CCTUInfo,
unsigned Priority, CXAvailabilityKind Availability)
- : Allocator(Allocator), CCTUInfo(CCTUInfo),
- Priority(Priority), Availability(Availability),
- BriefComment(nullptr) { }
+ : Allocator(Allocator), CCTUInfo(CCTUInfo), Priority(Priority),
+ Availability(Availability) {}
- /// \brief Retrieve the allocator into which the code completion
+ /// Retrieve the allocator into which the code completion
/// strings should be allocated.
CodeCompletionAllocator &getAllocator() const { return Allocator; }
CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }
- /// \brief Take the resulting completion string.
+ /// Take the resulting completion string.
///
/// This operation can only be performed once.
CodeCompletionString *TakeString();
- /// \brief Add a new typed-text chunk.
+ /// Add a new typed-text chunk.
void AddTypedTextChunk(const char *Text);
- /// \brief Add a new text chunk.
+ /// Add a new text chunk.
void AddTextChunk(const char *Text);
- /// \brief Add a new optional chunk.
+ /// Add a new optional chunk.
void AddOptionalChunk(CodeCompletionString *Optional);
- /// \brief Add a new placeholder chunk.
+ /// Add a new placeholder chunk.
void AddPlaceholderChunk(const char *Placeholder);
- /// \brief Add a new informative chunk.
+ /// Add a new informative chunk.
void AddInformativeChunk(const char *Text);
- /// \brief Add a new result-type chunk.
+ /// Add a new result-type chunk.
void AddResultTypeChunk(const char *ResultType);
- /// \brief Add a new current-parameter chunk.
+ /// Add a new current-parameter chunk.
void AddCurrentParameterChunk(const char *CurrentParameter);
- /// \brief Add a new chunk.
+ /// Add a new chunk.
void AddChunk(CodeCompletionString::ChunkKind CK, const char *Text = "");
void AddAnnotation(const char *A) { Annotations.push_back(A); }
- /// \brief Add the parent context information to this code completion.
+ /// Add the parent context information to this code completion.
void addParentContext(const DeclContext *DC);
const char *getBriefComment() const { return BriefComment; }
void addBriefComment(StringRef Comment);
-
+
StringRef getParentName() const { return ParentName; }
};
-/// \brief Captures a result of code completion.
+/// Captures a result of code completion.
class CodeCompletionResult {
public:
- /// \brief Describes the kind of result generated.
+ /// Describes the kind of result generated.
enum ResultKind {
- RK_Declaration = 0, ///< Refers to a declaration
- RK_Keyword, ///< Refers to a keyword or symbol.
- RK_Macro, ///< Refers to a macro
- RK_Pattern ///< Refers to a precomputed pattern.
+ /// Refers to a declaration.
+ RK_Declaration = 0,
+
+ /// Refers to a keyword or symbol.
+ RK_Keyword,
+
+ /// Refers to a macro.
+ RK_Macro,
+
+ /// Refers to a precomputed pattern.
+ RK_Pattern
};
- /// \brief When Kind == RK_Declaration or RK_Pattern, the declaration we are
+ /// When Kind == RK_Declaration or RK_Pattern, the declaration we are
/// referring to. In the latter case, the declaration might be NULL.
- const NamedDecl *Declaration;
+ const NamedDecl *Declaration = nullptr;
union {
- /// \brief When Kind == RK_Keyword, the string representing the keyword
+ /// When Kind == RK_Keyword, the string representing the keyword
/// or symbol's spelling.
const char *Keyword;
- /// \brief When Kind == RK_Pattern, the code-completion string that
+ /// When Kind == RK_Pattern, the code-completion string that
/// describes the completion text to insert.
CodeCompletionString *Pattern;
- /// \brief When Kind == RK_Macro, the identifier that refers to a macro.
+ /// When Kind == RK_Macro, the identifier that refers to a macro.
const IdentifierInfo *Macro;
};
- /// \brief The priority of this particular code-completion result.
+ /// The priority of this particular code-completion result.
unsigned Priority;
- /// \brief Specifies which parameter (of a function, Objective-C method,
+ /// Specifies which parameter (of a function, Objective-C method,
/// macro, etc.) we should start with when formatting the result.
- unsigned StartParameter;
+ unsigned StartParameter = 0;
- /// \brief The kind of result stored here.
+ /// The kind of result stored here.
ResultKind Kind;
- /// \brief The cursor kind that describes this result.
+ /// The cursor kind that describes this result.
CXCursorKind CursorKind;
- /// \brief The availability of this result.
- CXAvailabilityKind Availability;
+ /// The availability of this result.
+ CXAvailabilityKind Availability = CXAvailability_Available;
- /// \brief Whether this result is hidden by another name.
+ /// Fix-its that *must* be applied before inserting the text for the
+ /// corresponding completion.
+ ///
+ /// By default, CodeCompletionBuilder only returns completions with empty
+ /// fix-its. Extra completions with non-empty fix-its should be explicitly
+ /// requested by setting CompletionOptions::IncludeFixIts.
+ ///
+ /// For the clients to be able to compute position of the cursor after
+ /// applying fix-its, the following conditions are guaranteed to hold for
+ /// RemoveRange of the stored fix-its:
+ /// - Ranges in the fix-its are guaranteed to never contain the completion
+ /// point (or identifier under completion point, if any) inside them, except
+ /// at the start or at the end of the range.
+ /// - If a fix-it range starts or ends with completion point (or starts or
+ /// ends after the identifier under completion point), it will contain at
+ /// least one character. It allows to unambiguously recompute completion
+ /// point after applying the fix-it.
+ ///
+ /// The intuition is that provided fix-its change code around the identifier
+ /// we complete, but are not allowed to touch the identifier itself or the
+ /// completion point. One example of completions with corrections are the ones
+ /// replacing '.' with '->' and vice versa:
+ ///
+ /// std::unique_ptr<std::vector<int>> vec_ptr;
+ /// In 'vec_ptr.^', one of the completions is 'push_back', it requires
+ /// replacing '.' with '->'.
+ /// In 'vec_ptr->^', one of the completions is 'release', it requires
+ /// replacing '->' with '.'.
+ std::vector<FixItHint> FixIts;
+
+ /// Whether this result is hidden by another name.
bool Hidden : 1;
- /// \brief Whether this result was found via lookup into a base class.
+ /// Whether this result was found via lookup into a base class.
bool QualifierIsInformative : 1;
- /// \brief Whether this declaration is the beginning of a
+ /// Whether this declaration is the beginning of a
/// nested-name-specifier and, therefore, should be followed by '::'.
bool StartsNestedNameSpecifier : 1;
- /// \brief Whether all parameters (of a function, Objective-C
+ /// Whether all parameters (of a function, Objective-C
/// method, etc.) should be considered "informative".
bool AllParametersAreInformative : 1;
- /// \brief Whether we're completing a declaration of the given entity,
+ /// Whether we're completing a declaration of the given entity,
/// rather than a use of that entity.
bool DeclaringEntity : 1;
- /// \brief If the result should have a nested-name-specifier, this is it.
+ /// If the result should have a nested-name-specifier, this is it.
/// When \c QualifierIsInformative, the nested-name-specifier is
/// informative rather than required.
- NestedNameSpecifier *Qualifier;
+ NestedNameSpecifier *Qualifier = nullptr;
- /// \brief Build a result that refers to a declaration.
- CodeCompletionResult(const NamedDecl *Declaration,
- unsigned Priority,
+ /// If this Decl was unshadowed by using declaration, this can store a
+ /// pointer to the UsingShadowDecl which was used in the unshadowing process.
+ /// This information can be used to uprank CodeCompletionResults / which have
+ /// corresponding `using decl::qualified::name;` nearby.
+ const UsingShadowDecl *ShadowDecl = nullptr;
+
+ /// Build a result that refers to a declaration.
+ CodeCompletionResult(const NamedDecl *Declaration, unsigned Priority,
NestedNameSpecifier *Qualifier = nullptr,
bool QualifierIsInformative = false,
- bool Accessible = true)
- : Declaration(Declaration), Priority(Priority),
- StartParameter(0), Kind(RK_Declaration),
- Availability(CXAvailability_Available), Hidden(false),
- QualifierIsInformative(QualifierIsInformative),
- StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
- DeclaringEntity(false), Qualifier(Qualifier) {
+ bool Accessible = true,
+ std::vector<FixItHint> FixIts = std::vector<FixItHint>())
+ : Declaration(Declaration), Priority(Priority), Kind(RK_Declaration),
+ FixIts(std::move(FixIts)), Hidden(false),
+ QualifierIsInformative(QualifierIsInformative),
+ StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+ DeclaringEntity(false), Qualifier(Qualifier) {
+ // FIXME: Add assert to check FixIts range requirements.
computeCursorKindAndAvailability(Accessible);
}
- /// \brief Build a result that refers to a keyword or symbol.
+ /// Build a result that refers to a keyword or symbol.
CodeCompletionResult(const char *Keyword, unsigned Priority = CCP_Keyword)
- : Declaration(nullptr), Keyword(Keyword), Priority(Priority),
- StartParameter(0), Kind(RK_Keyword), CursorKind(CXCursor_NotImplemented),
- Availability(CXAvailability_Available), Hidden(false),
- QualifierIsInformative(0), StartsNestedNameSpecifier(false),
- AllParametersAreInformative(false), DeclaringEntity(false),
- Qualifier(nullptr) {}
-
- /// \brief Build a result that refers to a macro.
+ : Keyword(Keyword), Priority(Priority), Kind(RK_Keyword),
+ CursorKind(CXCursor_NotImplemented), Hidden(false),
+ QualifierIsInformative(false), StartsNestedNameSpecifier(false),
+ AllParametersAreInformative(false), DeclaringEntity(false) {}
+
+ /// Build a result that refers to a macro.
CodeCompletionResult(const IdentifierInfo *Macro,
unsigned Priority = CCP_Macro)
- : Declaration(nullptr), Macro(Macro), Priority(Priority), StartParameter(0),
- Kind(RK_Macro), CursorKind(CXCursor_MacroDefinition),
- Availability(CXAvailability_Available), Hidden(false),
- QualifierIsInformative(0), StartsNestedNameSpecifier(false),
- AllParametersAreInformative(false), DeclaringEntity(false),
- Qualifier(nullptr) {}
-
- /// \brief Build a result that refers to a pattern.
+ : Macro(Macro), Priority(Priority), Kind(RK_Macro),
+ CursorKind(CXCursor_MacroDefinition), Hidden(false),
+ QualifierIsInformative(false), StartsNestedNameSpecifier(false),
+ AllParametersAreInformative(false), DeclaringEntity(false) {}
+
+ /// Build a result that refers to a pattern.
CodeCompletionResult(CodeCompletionString *Pattern,
unsigned Priority = CCP_CodePattern,
CXCursorKind CursorKind = CXCursor_NotImplemented,
CXAvailabilityKind Availability = CXAvailability_Available,
const NamedDecl *D = nullptr)
- : Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0),
- Kind(RK_Pattern), CursorKind(CursorKind), Availability(Availability),
- Hidden(false), QualifierIsInformative(0),
- StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
- DeclaringEntity(false), Qualifier(nullptr)
- {
- }
+ : Declaration(D), Pattern(Pattern), Priority(Priority), Kind(RK_Pattern),
+ CursorKind(CursorKind), Availability(Availability), Hidden(false),
+ QualifierIsInformative(false), StartsNestedNameSpecifier(false),
+ AllParametersAreInformative(false), DeclaringEntity(false) {}
- /// \brief Build a result that refers to a pattern with an associated
+ /// Build a result that refers to a pattern with an associated
/// declaration.
CodeCompletionResult(CodeCompletionString *Pattern, const NamedDecl *D,
unsigned Priority)
- : Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0),
- Kind(RK_Pattern), Availability(CXAvailability_Available), Hidden(false),
- QualifierIsInformative(false), StartsNestedNameSpecifier(false),
- AllParametersAreInformative(false), DeclaringEntity(false),
- Qualifier(nullptr) {
+ : Declaration(D), Pattern(Pattern), Priority(Priority), Kind(RK_Pattern),
+ Hidden(false), QualifierIsInformative(false),
+ StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+ DeclaringEntity(false) {
computeCursorKindAndAvailability();
- }
-
- /// \brief Retrieve the declaration stored in this result.
+ }
+
+ /// Retrieve the declaration stored in this result. This might be nullptr if
+ /// Kind is RK_Pattern.
const NamedDecl *getDeclaration() const {
- assert(Kind == RK_Declaration && "Not a declaration result");
+ assert(((Kind == RK_Declaration) || (Kind == RK_Pattern)) &&
+ "Not a declaration or pattern result");
return Declaration;
}
- /// \brief Retrieve the keyword stored in this result.
+ /// Retrieve the keyword stored in this result.
const char *getKeyword() const {
assert(Kind == RK_Keyword && "Not a keyword result");
return Keyword;
}
- /// \brief Create a new code-completion string that describes how to insert
+ /// Create a new code-completion string that describes how to insert
/// this result into a program.
///
/// \param S The semantic analysis that created the result.
@@ -793,8 +927,15 @@ public:
CodeCompletionAllocator &Allocator,
CodeCompletionTUInfo &CCTUInfo,
bool IncludeBriefComments);
-
- /// \brief Retrieve the name that should be used to order a result.
+ /// Creates a new code-completion string for the macro result. Similar to the
+ /// above overloads, except this only requires preprocessor information.
+ /// The result kind must be `RK_Macro`.
+ CodeCompletionString *
+ CreateCodeCompletionStringForMacro(Preprocessor &PP,
+ CodeCompletionAllocator &Allocator,
+ CodeCompletionTUInfo &CCTUInfo);
+
+ /// Retrieve the name that should be used to order a result.
///
/// If the name needs to be constructed as a string, that string will be
/// saved into Saved and the returned StringRef will refer to it.
@@ -821,80 +962,81 @@ inline bool operator>=(const CodeCompletionResult &X,
return !(X < Y);
}
-
raw_ostream &operator<<(raw_ostream &OS,
const CodeCompletionString &CCS);
-/// \brief Abstract interface for a consumer of code-completion
+/// Abstract interface for a consumer of code-completion
/// information.
class CodeCompleteConsumer {
protected:
const CodeCompleteOptions CodeCompleteOpts;
- /// \brief Whether the output format for the code-completion consumer is
+ /// Whether the output format for the code-completion consumer is
/// binary.
bool OutputIsBinary;
public:
class OverloadCandidate {
public:
- /// \brief Describes the type of overload candidate.
+ /// Describes the type of overload candidate.
enum CandidateKind {
- /// \brief The candidate is a function declaration.
+ /// The candidate is a function declaration.
CK_Function,
- /// \brief The candidate is a function template.
+
+ /// The candidate is a function template.
CK_FunctionTemplate,
- /// \brief The "candidate" is actually a variable, expression, or block
+
+ /// The "candidate" is actually a variable, expression, or block
/// for which we only have a function prototype.
CK_FunctionType
};
private:
- /// \brief The kind of overload candidate.
+ /// The kind of overload candidate.
CandidateKind Kind;
union {
- /// \brief The function overload candidate, available when
+ /// The function overload candidate, available when
/// Kind == CK_Function.
FunctionDecl *Function;
- /// \brief The function template overload candidate, available when
+ /// The function template overload candidate, available when
/// Kind == CK_FunctionTemplate.
FunctionTemplateDecl *FunctionTemplate;
- /// \brief The function type that describes the entity being called,
+ /// The function type that describes the entity being called,
/// when Kind == CK_FunctionType.
const FunctionType *Type;
};
public:
OverloadCandidate(FunctionDecl *Function)
- : Kind(CK_Function), Function(Function) { }
+ : Kind(CK_Function), Function(Function) {}
OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl)
- : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) { }
+ : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) {}
OverloadCandidate(const FunctionType *Type)
- : Kind(CK_FunctionType), Type(Type) { }
+ : Kind(CK_FunctionType), Type(Type) {}
- /// \brief Determine the kind of overload candidate.
+ /// Determine the kind of overload candidate.
CandidateKind getKind() const { return Kind; }
- /// \brief Retrieve the function overload candidate or the templated
+ /// Retrieve the function overload candidate or the templated
/// function declaration for a function template.
FunctionDecl *getFunction() const;
- /// \brief Retrieve the function template overload candidate.
+ /// Retrieve the function template overload candidate.
FunctionTemplateDecl *getFunctionTemplate() const {
assert(getKind() == CK_FunctionTemplate && "Not a function template");
return FunctionTemplate;
}
- /// \brief Retrieve the function type of the entity, regardless of how the
+ /// Retrieve the function type of the entity, regardless of how the
/// function is stored.
const FunctionType *getFunctionType() const;
- /// \brief Create a new code-completion string that describes the function
+ /// Create a new code-completion string that describes the function
/// signature of this overload candidate.
CodeCompletionString *CreateSignatureString(unsigned CurrentArg,
Sema &S,
@@ -905,43 +1047,52 @@ public:
CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
bool OutputIsBinary)
- : CodeCompleteOpts(CodeCompleteOpts), OutputIsBinary(OutputIsBinary)
- { }
+ : CodeCompleteOpts(CodeCompleteOpts), OutputIsBinary(OutputIsBinary) {}
- /// \brief Whether the code-completion consumer wants to see macros.
+ /// Whether the code-completion consumer wants to see macros.
bool includeMacros() const {
return CodeCompleteOpts.IncludeMacros;
}
- /// \brief Whether the code-completion consumer wants to see code patterns.
+ /// Whether the code-completion consumer wants to see code patterns.
bool includeCodePatterns() const {
return CodeCompleteOpts.IncludeCodePatterns;
}
- /// \brief Whether to include global (top-level) declaration results.
+ /// Whether to include global (top-level) declaration results.
bool includeGlobals() const { return CodeCompleteOpts.IncludeGlobals; }
- /// \brief Whether to include declarations in namespace contexts (including
+ /// Whether to include declarations in namespace contexts (including
/// the global namespace). If this is false, `includeGlobals()` will be
/// ignored.
bool includeNamespaceLevelDecls() const {
return CodeCompleteOpts.IncludeNamespaceLevelDecls;
}
- /// \brief Whether to include brief documentation comments within the set of
+ /// Whether to include brief documentation comments within the set of
/// code completions returned.
bool includeBriefComments() const {
return CodeCompleteOpts.IncludeBriefComments;
}
- /// \brief Determine whether the output of this consumer is binary.
+ /// Whether to include completion items with small fix-its, e.g. change
+ /// '.' to '->' on member access, etc.
+ bool includeFixIts() const { return CodeCompleteOpts.IncludeFixIts; }
+
+ /// Hint whether to load data from the external AST in order to provide
+ /// full results. If false, declarations from the preamble may be omitted.
+ bool loadExternal() const {
+ return CodeCompleteOpts.LoadExternal;
+ }
+
+ /// Determine whether the output of this consumer is binary.
bool isOutputBinary() const { return OutputIsBinary; }
- /// \brief Deregisters and destroys this code-completion consumer.
+ /// Deregisters and destroys this code-completion consumer.
virtual ~CodeCompleteConsumer();
/// \name Code-completion filtering
- /// \brief Check if the result should be filtered out.
+ /// Check if the result should be filtered out.
virtual bool isResultFilteredOut(StringRef Filter,
CodeCompletionResult Results) {
return false;
@@ -949,11 +1100,11 @@ public:
/// \name Code-completion callbacks
//@{
- /// \brief Process the finalized code-completion results.
+ /// Process the finalized code-completion results.
virtual void ProcessCodeCompleteResults(Sema &S,
CodeCompletionContext Context,
CodeCompletionResult *Results,
- unsigned NumResults) { }
+ unsigned NumResults) {}
/// \param S the semantic-analyzer object for which code-completion is being
/// done.
@@ -965,33 +1116,50 @@ public:
/// \param NumCandidates the number of overload candidates
virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
OverloadCandidate *Candidates,
- unsigned NumCandidates) { }
+ unsigned NumCandidates) {}
//@}
- /// \brief Retrieve the allocator that will be used to allocate
+ /// Retrieve the allocator that will be used to allocate
/// code completion strings.
virtual CodeCompletionAllocator &getAllocator() = 0;
virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() = 0;
};
-/// \brief A simple code-completion consumer that prints the results it
+/// Get the documentation comment used to produce
+/// CodeCompletionString::BriefComment for RK_Declaration.
+const RawComment *getCompletionComment(const ASTContext &Ctx,
+ const NamedDecl *Decl);
+
+/// Get the documentation comment used to produce
+/// CodeCompletionString::BriefComment for RK_Pattern.
+const RawComment *getPatternCompletionComment(const ASTContext &Ctx,
+ const NamedDecl *Decl);
+
+/// Get the documentation comment used to produce
+/// CodeCompletionString::BriefComment for OverloadCandidate.
+const RawComment *
+getParameterComment(const ASTContext &Ctx,
+ const CodeCompleteConsumer::OverloadCandidate &Result,
+ unsigned ArgIndex);
+
+/// A simple code-completion consumer that prints the results it
/// receives in a simple format.
class PrintingCodeCompleteConsumer : public CodeCompleteConsumer {
- /// \brief The raw output stream.
+ /// The raw output stream.
raw_ostream &OS;
CodeCompletionTUInfo CCTUInfo;
public:
- /// \brief Create a new printing code-completion consumer that prints its
+ /// Create a new printing code-completion consumer that prints its
/// results to the given raw output stream.
PrintingCodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
raw_ostream &OS)
: CodeCompleteConsumer(CodeCompleteOpts, false), OS(OS),
CCTUInfo(std::make_shared<GlobalCodeCompletionAllocator>()) {}
- /// \brief Prints the finalized code-completion results.
+ /// Prints the finalized code-completion results.
void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
CodeCompletionResult *Results,
unsigned NumResults) override;
@@ -1009,6 +1177,6 @@ public:
CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
};
-} // end namespace clang
+} // namespace clang
#endif // LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
diff --git a/include/clang/Sema/CodeCompleteOptions.h b/include/clang/Sema/CodeCompleteOptions.h
index 091d8ca60505e..1d3bbb4e585d7 100644
--- a/include/clang/Sema/CodeCompleteOptions.h
+++ b/include/clang/Sema/CodeCompleteOptions.h
@@ -35,9 +35,18 @@ public:
/// Show brief documentation comments in code completion results.
unsigned IncludeBriefComments : 1;
+ /// Hint whether to load data from the external AST to provide full results.
+ /// If false, namespace-level declarations from the preamble may be omitted.
+ unsigned LoadExternal : 1;
+
+ /// Include results after corrections (small fix-its), e.g. change '.' to '->'
+ /// on member access, etc.
+ unsigned IncludeFixIts : 1;
+
CodeCompleteOptions()
: IncludeMacros(0), IncludeCodePatterns(0), IncludeGlobals(1),
- IncludeNamespaceLevelDecls(1), IncludeBriefComments(0) {}
+ IncludeNamespaceLevelDecls(1), IncludeBriefComments(0),
+ LoadExternal(1), IncludeFixIts(0) {}
};
} // namespace clang
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 760a04d3c8d2e..83d5ab2cff85d 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief This file defines the classes used to store parsed information about
+/// This file defines the classes used to store parsed information about
/// declaration-specifiers and declarators.
///
/// \verbatim
@@ -29,8 +29,8 @@
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Lex/Token.h"
-#include "clang/Sema/AttributeList.h"
#include "clang/Sema/Ownership.h"
+#include "clang/Sema/ParsedAttr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
@@ -48,7 +48,7 @@ namespace clang {
class Declarator;
struct TemplateIdAnnotation;
-/// \brief Represents a C++ nested-name-specifier or a global scope specifier.
+/// Represents a C++ nested-name-specifier or a global scope specifier.
///
/// These can be in 3 states:
/// 1) Not present, identified by isEmpty()
@@ -72,12 +72,12 @@ public:
SourceLocation getBeginLoc() const { return Range.getBegin(); }
SourceLocation getEndLoc() const { return Range.getEnd(); }
- /// \brief Retrieve the representation of the nested-name-specifier.
+ /// Retrieve the representation of the nested-name-specifier.
NestedNameSpecifier *getScopeRep() const {
return Builder.getRepresentation();
}
- /// \brief Extend the current nested-name-specifier by another
+ /// Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'type::'.
///
/// \param Context The AST context in which this nested-name-specifier
@@ -91,7 +91,7 @@ public:
void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
SourceLocation ColonColonLoc);
- /// \brief Extend the current nested-name-specifier by another
+ /// Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'identifier::'.
///
/// \param Context The AST context in which this nested-name-specifier
@@ -105,7 +105,7 @@ public:
void Extend(ASTContext &Context, IdentifierInfo *Identifier,
SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
- /// \brief Extend the current nested-name-specifier by another
+ /// Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'namespace::'.
///
/// \param Context The AST context in which this nested-name-specifier
@@ -119,7 +119,7 @@ public:
void Extend(ASTContext &Context, NamespaceDecl *Namespace,
SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
- /// \brief Extend the current nested-name-specifier by another
+ /// Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'namespace-alias::'.
///
/// \param Context The AST context in which this nested-name-specifier
@@ -134,11 +134,11 @@ public:
void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
SourceLocation AliasLoc, SourceLocation ColonColonLoc);
- /// \brief Turn this (empty) nested-name-specifier into the global
+ /// Turn this (empty) nested-name-specifier into the global
/// nested-name-specifier '::'.
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
- /// \brief Turns this (empty) nested-name-specifier into '__super'
+ /// Turns this (empty) nested-name-specifier into '__super'
/// nested-name-specifier.
///
/// \param Context The AST context in which this nested-name-specifier
@@ -154,7 +154,7 @@ public:
void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
SourceLocation SuperLoc, SourceLocation ColonColonLoc);
- /// \brief Make a new nested-name-specifier from incomplete source-location
+ /// Make a new nested-name-specifier from incomplete source-location
/// information.
///
/// FIXME: This routine should be used very, very rarely, in cases where we
@@ -163,18 +163,18 @@ public:
void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
SourceRange R);
- /// \brief Adopt an existing nested-name-specifier (with source-range
+ /// Adopt an existing nested-name-specifier (with source-range
/// information).
void Adopt(NestedNameSpecifierLoc Other);
- /// \brief Retrieve a nested-name-specifier with location information, copied
+ /// Retrieve a nested-name-specifier with location information, copied
/// into the given AST context.
///
/// \param Context The context into which this nested-name-specifier will be
/// copied.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
- /// \brief Retrieve the location of the name in the last qualifier
+ /// Retrieve the location of the name in the last qualifier
/// in this nested name specifier.
///
/// For example, the location of \c bar
@@ -195,7 +195,7 @@ public:
/// A scope specifier is present, and it refers to a real scope.
bool isValid() const { return isNotEmpty() && getScopeRep() != nullptr; }
- /// \brief Indicate that this nested-name-specifier is invalid.
+ /// Indicate that this nested-name-specifier is invalid.
void SetInvalid(SourceRange R) {
assert(R.isValid() && "Must have a valid source range");
if (Range.getBegin().isInvalid())
@@ -213,21 +213,21 @@ public:
Builder.Clear();
}
- /// \brief Retrieve the data associated with the source-location information.
+ /// Retrieve the data associated with the source-location information.
char *location_data() const { return Builder.getBuffer().first; }
- /// \brief Retrieve the size of the data associated with source-location
+ /// Retrieve the size of the data associated with source-location
/// information.
unsigned location_size() const { return Builder.getBuffer().second; }
};
-/// \brief Captures information about "declaration specifiers".
+/// Captures information about "declaration specifiers".
///
/// "Declaration specifiers" encompasses storage-class-specifiers,
/// type-specifiers, type-qualifiers, and function-specifiers.
class DeclSpec {
public:
- /// \brief storage-class-specifier
+ /// storage-class-specifier
/// \note The order of these enumerators is important for diagnostics.
enum SCS {
SCS_unspecified = 0,
@@ -273,6 +273,7 @@ public:
static const TST TST_void = clang::TST_void;
static const TST TST_char = clang::TST_char;
static const TST TST_wchar = clang::TST_wchar;
+ static const TST TST_char8 = clang::TST_char8;
static const TST TST_char16 = clang::TST_char16;
static const TST TST_char32 = clang::TST_char32;
static const TST TST_int = clang::TST_int;
@@ -281,6 +282,8 @@ public:
static const TST TST_float = clang::TST_float;
static const TST TST_double = clang::TST_double;
static const TST TST_float16 = clang::TST_Float16;
+ static const TST TST_accum = clang::TST_Accum;
+ static const TST TST_fract = clang::TST_Fract;
static const TST TST_float128 = clang::TST_float128;
static const TST TST_bool = clang::TST_bool;
static const TST TST_decimal32 = clang::TST_decimal32;
@@ -326,6 +329,7 @@ public:
PQ_TypeSpecifier = 2,
PQ_TypeQualifier = 4,
PQ_FunctionSpecifier = 8
+ // FIXME: Attributes should be included here.
};
private:
@@ -344,6 +348,7 @@ private:
unsigned TypeAltiVecBool : 1;
unsigned TypeSpecOwned : 1;
unsigned TypeSpecPipe : 1;
+ unsigned TypeSpecSat : 1;
// type-qualifiers
unsigned TypeQualifiers : 5; // Bitwise OR of TQ.
@@ -379,7 +384,7 @@ private:
SourceLocation StorageClassSpecLoc, ThreadStorageClassSpecLoc;
SourceRange TSWRange;
- SourceLocation TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
+ SourceLocation TSCLoc, TSSLoc, TSTLoc, AltiVecLoc, TSSatLoc;
/// TSTNameLoc - If TypeSpecType is any of class, enum, struct, union,
/// typename, then this is the location of the named type (if present);
/// otherwise, it is the same as TSTLoc. Hence, the pair TSTLoc and
@@ -428,6 +433,7 @@ public:
TypeAltiVecBool(false),
TypeSpecOwned(false),
TypeSpecPipe(false),
+ TypeSpecSat(false),
TypeQualifiers(TQ_unspecified),
FS_inline_specified(false),
FS_forceinline_specified(false),
@@ -481,6 +487,7 @@ public:
bool isTypeSpecOwned() const { return TypeSpecOwned; }
bool isTypeRep() const { return isTypeRep((TST) TypeSpecType); }
bool isTypeSpecPipe() const { return TypeSpecPipe; }
+ bool isTypeSpecSat() const { return TypeSpecSat; }
ParsedType getRepAsType() const {
assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type");
@@ -507,6 +514,7 @@ public:
SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; }
SourceLocation getAltiVecLoc() const { return AltiVecLoc; }
+ SourceLocation getTypeSpecSatLoc() const { return TSSatLoc; }
SourceLocation getTypeSpecTypeNameLoc() const {
assert(isDeclRep((TST) TypeSpecType) || TypeSpecType == TST_typename);
@@ -523,7 +531,7 @@ public:
bool hasTagDefinition() const;
- /// \brief Turn a type-specifier-type into a string like "_Bool" or "union".
+ /// Turn a type-specifier-type into a string like "_Bool" or "union".
static const char *getSpecifierName(DeclSpec::TST T,
const PrintingPolicy &Policy);
static const char *getSpecifierName(DeclSpec::TQ Q);
@@ -544,7 +552,7 @@ public:
SourceLocation getUnalignedSpecLoc() const { return TQ_unalignedLoc; }
SourceLocation getPipeLoc() const { return TQ_pipeLoc; }
- /// \brief Clear out all of the type qualifiers.
+ /// Clear out all of the type qualifiers.
void ClearTypeQualifiers() {
TypeQualifiers = 0;
TQ_constLoc = SourceLocation();
@@ -585,7 +593,7 @@ public:
FS_noreturnLoc = SourceLocation();
}
- /// \brief Return true if any type-specifier has been found.
+ /// Return true if any type-specifier has been found.
bool hasTypeSpecifier() const {
return getTypeSpecType() != DeclSpec::TST_unspecified ||
getTypeSpecWidth() != DeclSpec::TSW_unspecified ||
@@ -593,7 +601,7 @@ public:
getTypeSpecSign() != DeclSpec::TSS_unspecified;
}
- /// \brief Return a bitmask of which flavors of specifiers this
+ /// Return a bitmask of which flavors of specifiers this
/// DeclSpec includes.
unsigned getParsedSpecifiers() const;
@@ -659,6 +667,8 @@ public:
bool SetTypePipe(bool isPipe, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID,
const PrintingPolicy &Policy);
+ bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
bool SetTypeSpecError();
void UpdateDeclRep(Decl *Rep) {
assert(isDeclRep((TST) TypeSpecType));
@@ -712,7 +722,7 @@ public:
return Attrs.getPool();
}
- /// \brief Concatenates two attribute lists.
+ /// Concatenates two attribute lists.
///
/// The GCC attribute syntax allows for the following:
///
@@ -729,8 +739,8 @@ public:
/// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
/// \endcode
///
- void addAttributes(AttributeList *AL) {
- Attrs.addAll(AL);
+ void addAttributes(ParsedAttributesView &AL) {
+ Attrs.addAll(AL.begin(), AL.end());
}
bool hasAttributes() const { return !Attrs.empty(); }
@@ -754,13 +764,13 @@ public:
ObjCDeclSpec *getObjCQualifiers() const { return ObjCQualifiers; }
void setObjCQualifiers(ObjCDeclSpec *quals) { ObjCQualifiers = quals; }
- /// \brief Checks if this DeclSpec can stand alone, without a Declarator.
+ /// Checks if this DeclSpec can stand alone, without a Declarator.
///
/// Only tag declspecs can stand alone.
bool isMissingDeclaratorOk();
};
-/// \brief Captures information about "declaration specifiers" specific to
+/// Captures information about "declaration specifiers" specific to
/// Objective-C.
class ObjCDeclSpec {
public:
@@ -882,42 +892,45 @@ private:
};
-/// \brief Represents a C++ unqualified-id that has been parsed.
+/// Describes the kind of unqualified-id parsed.
+enum class UnqualifiedIdKind {
+ /// An identifier.
+ IK_Identifier,
+ /// An overloaded operator name, e.g., operator+.
+ IK_OperatorFunctionId,
+ /// A conversion function name, e.g., operator int.
+ IK_ConversionFunctionId,
+ /// A user-defined literal name, e.g., operator "" _i.
+ IK_LiteralOperatorId,
+ /// A constructor name.
+ IK_ConstructorName,
+ /// A constructor named via a template-id.
+ IK_ConstructorTemplateId,
+ /// A destructor name.
+ IK_DestructorName,
+ /// A template-id, e.g., f<int>.
+ IK_TemplateId,
+ /// An implicit 'self' parameter
+ IK_ImplicitSelfParam,
+ /// A deduction-guide name (a template-name)
+ IK_DeductionGuideName
+};
+
+/// Represents a C++ unqualified-id that has been parsed.
class UnqualifiedId {
private:
UnqualifiedId(const UnqualifiedId &Other) = delete;
const UnqualifiedId &operator=(const UnqualifiedId &) = delete;
public:
- /// \brief Describes the kind of unqualified-id parsed.
- enum IdKind {
- /// \brief An identifier.
- IK_Identifier,
- /// \brief An overloaded operator name, e.g., operator+.
- IK_OperatorFunctionId,
- /// \brief A conversion function name, e.g., operator int.
- IK_ConversionFunctionId,
- /// \brief A user-defined literal name, e.g., operator "" _i.
- IK_LiteralOperatorId,
- /// \brief A constructor name.
- IK_ConstructorName,
- /// \brief A constructor named via a template-id.
- IK_ConstructorTemplateId,
- /// \brief A destructor name.
- IK_DestructorName,
- /// \brief A template-id, e.g., f<int>.
- IK_TemplateId,
- /// \brief An implicit 'self' parameter
- IK_ImplicitSelfParam,
- /// \brief A deduction-guide name (a template-name)
- IK_DeductionGuideName
- } Kind;
+ /// Describes the kind of unqualified-id parsed.
+ UnqualifiedIdKind Kind;
struct OFI {
- /// \brief The kind of overloaded operator.
+ /// The kind of overloaded operator.
OverloadedOperatorKind Operator;
- /// \brief The source locations of the individual tokens that name
+ /// The source locations of the individual tokens that name
/// the operator, e.g., the "new", "[", and "]" tokens in
/// operator new [].
///
@@ -927,78 +940,79 @@ public:
unsigned SymbolLocations[3];
};
- /// \brief Anonymous union that holds extra data associated with the
+ /// Anonymous union that holds extra data associated with the
/// parsed unqualified-id.
union {
- /// \brief When Kind == IK_Identifier, the parsed identifier, or when
+ /// When Kind == IK_Identifier, the parsed identifier, or when
/// Kind == IK_UserLiteralId, the identifier suffix.
IdentifierInfo *Identifier;
- /// \brief When Kind == IK_OperatorFunctionId, the overloaded operator
+ /// When Kind == IK_OperatorFunctionId, the overloaded operator
/// that we parsed.
struct OFI OperatorFunctionId;
- /// \brief When Kind == IK_ConversionFunctionId, the type that the
+ /// When Kind == IK_ConversionFunctionId, the type that the
/// conversion function names.
UnionParsedType ConversionFunctionId;
- /// \brief When Kind == IK_ConstructorName, the class-name of the type
+ /// When Kind == IK_ConstructorName, the class-name of the type
/// whose constructor is being referenced.
UnionParsedType ConstructorName;
- /// \brief When Kind == IK_DestructorName, the type referred to by the
+ /// When Kind == IK_DestructorName, the type referred to by the
/// class-name.
UnionParsedType DestructorName;
- /// \brief When Kind == IK_DeductionGuideName, the parsed template-name.
+ /// When Kind == IK_DeductionGuideName, the parsed template-name.
UnionParsedTemplateTy TemplateName;
- /// \brief When Kind == IK_TemplateId or IK_ConstructorTemplateId,
+ /// When Kind == IK_TemplateId or IK_ConstructorTemplateId,
/// the template-id annotation that contains the template name and
/// template arguments.
TemplateIdAnnotation *TemplateId;
};
- /// \brief The location of the first token that describes this unqualified-id,
+ /// The location of the first token that describes this unqualified-id,
/// which will be the location of the identifier, "operator" keyword,
/// tilde (for a destructor), or the template name of a template-id.
SourceLocation StartLocation;
- /// \brief The location of the last token that describes this unqualified-id.
+ /// The location of the last token that describes this unqualified-id.
SourceLocation EndLocation;
-
- UnqualifiedId() : Kind(IK_Identifier), Identifier(nullptr) { }
- /// \brief Clear out this unqualified-id, setting it to default (invalid)
+ UnqualifiedId()
+ : Kind(UnqualifiedIdKind::IK_Identifier), Identifier(nullptr) {}
+
+ /// Clear out this unqualified-id, setting it to default (invalid)
/// state.
void clear() {
- Kind = IK_Identifier;
+ Kind = UnqualifiedIdKind::IK_Identifier;
Identifier = nullptr;
StartLocation = SourceLocation();
EndLocation = SourceLocation();
}
- /// \brief Determine whether this unqualified-id refers to a valid name.
+ /// Determine whether this unqualified-id refers to a valid name.
bool isValid() const { return StartLocation.isValid(); }
- /// \brief Determine whether this unqualified-id refers to an invalid name.
+ /// Determine whether this unqualified-id refers to an invalid name.
bool isInvalid() const { return !isValid(); }
- /// \brief Determine what kind of name we have.
- IdKind getKind() const { return Kind; }
- void setKind(IdKind kind) { Kind = kind; }
+ /// Determine what kind of name we have.
+ UnqualifiedIdKind getKind() const { return Kind; }
+ void setKind(UnqualifiedIdKind kind) { Kind = kind; }
- /// \brief Specify that this unqualified-id was parsed as an identifier.
+ /// Specify that this unqualified-id was parsed as an identifier.
///
/// \param Id the parsed identifier.
/// \param IdLoc the location of the parsed identifier.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc) {
- Kind = IK_Identifier;
+ Kind = UnqualifiedIdKind::IK_Identifier;
Identifier = const_cast<IdentifierInfo *>(Id);
StartLocation = EndLocation = IdLoc;
}
- /// \brief Specify that this unqualified-id was parsed as an
+ /// Specify that this unqualified-id was parsed as an
/// operator-function-id.
///
/// \param OperatorLoc the location of the 'operator' keyword.
@@ -1011,7 +1025,7 @@ public:
OverloadedOperatorKind Op,
SourceLocation SymbolLocations[3]);
- /// \brief Specify that this unqualified-id was parsed as a
+ /// Specify that this unqualified-id was parsed as a
/// conversion-function-id.
///
/// \param OperatorLoc the location of the 'operator' keyword.
@@ -1022,13 +1036,13 @@ public:
void setConversionFunctionId(SourceLocation OperatorLoc,
ParsedType Ty,
SourceLocation EndLoc) {
- Kind = IK_ConversionFunctionId;
+ Kind = UnqualifiedIdKind::IK_ConversionFunctionId;
StartLocation = OperatorLoc;
EndLocation = EndLoc;
ConversionFunctionId = Ty;
}
- /// \brief Specific that this unqualified-id was parsed as a
+ /// Specific that this unqualified-id was parsed as a
/// literal-operator-id.
///
/// \param Id the parsed identifier.
@@ -1038,13 +1052,13 @@ public:
/// \param IdLoc the location of the identifier.
void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc,
SourceLocation IdLoc) {
- Kind = IK_LiteralOperatorId;
+ Kind = UnqualifiedIdKind::IK_LiteralOperatorId;
Identifier = const_cast<IdentifierInfo *>(Id);
StartLocation = OpLoc;
EndLocation = IdLoc;
}
- /// \brief Specify that this unqualified-id was parsed as a constructor name.
+ /// Specify that this unqualified-id was parsed as a constructor name.
///
/// \param ClassType the class type referred to by the constructor name.
///
@@ -1054,13 +1068,13 @@ public:
void setConstructorName(ParsedType ClassType,
SourceLocation ClassNameLoc,
SourceLocation EndLoc) {
- Kind = IK_ConstructorName;
+ Kind = UnqualifiedIdKind::IK_ConstructorName;
StartLocation = ClassNameLoc;
EndLocation = EndLoc;
ConstructorName = ClassType;
}
- /// \brief Specify that this unqualified-id was parsed as a
+ /// Specify that this unqualified-id was parsed as a
/// template-id that names a constructor.
///
/// \param TemplateId the template-id annotation that describes the parsed
@@ -1068,7 +1082,7 @@ public:
/// \p TemplateId and will free it on destruction.
void setConstructorTemplateId(TemplateIdAnnotation *TemplateId);
- /// \brief Specify that this unqualified-id was parsed as a destructor name.
+ /// Specify that this unqualified-id was parsed as a destructor name.
///
/// \param TildeLoc the location of the '~' that introduces the destructor
/// name.
@@ -1077,32 +1091,32 @@ public:
void setDestructorName(SourceLocation TildeLoc,
ParsedType ClassType,
SourceLocation EndLoc) {
- Kind = IK_DestructorName;
+ Kind = UnqualifiedIdKind::IK_DestructorName;
StartLocation = TildeLoc;
EndLocation = EndLoc;
DestructorName = ClassType;
}
- /// \brief Specify that this unqualified-id was parsed as a template-id.
+ /// Specify that this unqualified-id was parsed as a template-id.
///
/// \param TemplateId the template-id annotation that describes the parsed
/// template-id. This UnqualifiedId instance will take ownership of the
/// \p TemplateId and will free it on destruction.
void setTemplateId(TemplateIdAnnotation *TemplateId);
- /// \brief Specify that this unqualified-id was parsed as a template-name for
+ /// Specify that this unqualified-id was parsed as a template-name for
/// a deduction-guide.
///
/// \param Template The parsed template-name.
/// \param TemplateLoc The location of the parsed template-name.
void setDeductionGuideName(ParsedTemplateTy Template,
SourceLocation TemplateLoc) {
- Kind = IK_DeductionGuideName;
+ Kind = UnqualifiedIdKind::IK_DeductionGuideName;
TemplateName = Template;
StartLocation = EndLocation = TemplateLoc;
}
- /// \brief Return the source range that covers this unqualified-id.
+ /// Return the source range that covers this unqualified-id.
SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(StartLocation, EndLocation);
}
@@ -1110,10 +1124,10 @@ public:
SourceLocation getLocEnd() const LLVM_READONLY { return EndLocation; }
};
-/// \brief A set of tokens that has been cached for later parsing.
+/// A set of tokens that has been cached for later parsing.
typedef SmallVector<Token, 4> CachedTokens;
-/// \brief One instance of this struct is used for each type in a
+/// One instance of this struct is used for each type in a
/// declarator that is parsed.
///
/// This is intended to be a small value object.
@@ -1133,11 +1147,9 @@ struct DeclaratorChunk {
return SourceRange(Loc, EndLoc);
}
- struct TypeInfoCommon {
- AttributeList *AttrList;
- };
+ ParsedAttributesView AttrList;
- struct PointerTypeInfo : TypeInfoCommon {
+ struct PointerTypeInfo {
/// The type qualifiers: const/volatile/restrict/unaligned/atomic.
unsigned TypeQuals : 5;
@@ -1160,7 +1172,7 @@ struct DeclaratorChunk {
}
};
- struct ReferenceTypeInfo : TypeInfoCommon {
+ struct ReferenceTypeInfo {
/// The type qualifier: restrict. [GNU] C++ extension
bool HasRestrict : 1;
/// True if this is an lvalue reference, false if it's an rvalue reference.
@@ -1169,7 +1181,7 @@ struct DeclaratorChunk {
}
};
- struct ArrayTypeInfo : TypeInfoCommon {
+ struct ArrayTypeInfo {
/// The type qualifiers for the array:
/// const/volatile/restrict/__unaligned/_Atomic.
unsigned TypeQuals : 5;
@@ -1220,7 +1232,7 @@ struct DeclaratorChunk {
SourceRange Range;
};
- struct FunctionTypeInfo : TypeInfoCommon {
+ struct FunctionTypeInfo {
/// hasPrototype - This is true if the function had at least one typed
/// parameter. If the function is () or (a,b,c), then it has no prototype,
/// and is treated as a K&R-style function.
@@ -1234,7 +1246,7 @@ struct DeclaratorChunk {
/// Can this declaration be a constructor-style initializer?
unsigned isAmbiguous : 1;
- /// \brief Whether the ref-qualifier (if any) is an lvalue reference.
+ /// Whether the ref-qualifier (if any) is an lvalue reference.
/// Otherwise, it's an rvalue reference.
unsigned RefQualifierIsLValueRef : 1;
@@ -1270,34 +1282,34 @@ struct DeclaratorChunk {
/// number of declarations in the function prototype.
unsigned NumExceptionsOrDecls;
- /// \brief The location of the ref-qualifier, if any.
+ /// The location of the ref-qualifier, if any.
///
/// If this is an invalid location, there is no ref-qualifier.
unsigned RefQualifierLoc;
- /// \brief The location of the const-qualifier, if any.
+ /// The location of the const-qualifier, if any.
///
/// If this is an invalid location, there is no const-qualifier.
unsigned ConstQualifierLoc;
- /// \brief The location of the volatile-qualifier, if any.
+ /// The location of the volatile-qualifier, if any.
///
/// If this is an invalid location, there is no volatile-qualifier.
unsigned VolatileQualifierLoc;
- /// \brief The location of the restrict-qualifier, if any.
+ /// The location of the restrict-qualifier, if any.
///
/// If this is an invalid location, there is no restrict-qualifier.
unsigned RestrictQualifierLoc;
- /// \brief The location of the 'mutable' qualifer in a lambda-declarator, if
+ /// The location of the 'mutable' qualifer in a lambda-declarator, if
/// any.
unsigned MutableLoc;
- /// \brief The beginning location of the exception specification, if any.
+ /// The beginning location of the exception specification, if any.
unsigned ExceptionSpecLocBeg;
- /// \brief The end location of the exception specification, if any.
+ /// The end location of the exception specification, if any.
unsigned ExceptionSpecLocEnd;
/// Params - This is a pointer to a new[]'d array of ParamInfo objects that
@@ -1306,16 +1318,16 @@ struct DeclaratorChunk {
ParamInfo *Params;
union {
- /// \brief Pointer to a new[]'d array of TypeAndRange objects that
+ /// Pointer to a new[]'d array of TypeAndRange objects that
/// contain the types in the function's dynamic exception specification
/// and their locations, if there is one.
TypeAndRange *Exceptions;
- /// \brief Pointer to the expression in the noexcept-specifier of this
+ /// Pointer to the expression in the noexcept-specifier of this
/// function, if it has one.
Expr *NoexceptExpr;
- /// \brief Pointer to the cached tokens for an exception-specification
+ /// Pointer to the cached tokens for an exception-specification
/// that has not yet been parsed.
CachedTokens *ExceptionSpecTokens;
@@ -1325,11 +1337,11 @@ struct DeclaratorChunk {
NamedDecl **DeclsInPrototype;
};
- /// \brief If HasTrailingReturnType is true, this is the trailing return
+ /// If HasTrailingReturnType is true, this is the trailing return
/// type specified.
UnionParsedType TrailingReturnType;
- /// \brief Reset the parameter list to having zero parameters.
+ /// Reset the parameter list to having zero parameters.
///
/// This is used in various places for error recovery.
void freeParams() {
@@ -1343,8 +1355,7 @@ struct DeclaratorChunk {
}
void destroy() {
- if (DeleteParams)
- delete[] Params;
+ freeParams();
switch (getExceptionSpecType()) {
default:
break;
@@ -1390,66 +1401,66 @@ struct DeclaratorChunk {
return SourceRange(getExceptionSpecLocBeg(), getExceptionSpecLocEnd());
}
- /// \brief Retrieve the location of the ref-qualifier, if any.
+ /// Retrieve the location of the ref-qualifier, if any.
SourceLocation getRefQualifierLoc() const {
return SourceLocation::getFromRawEncoding(RefQualifierLoc);
}
- /// \brief Retrieve the location of the 'const' qualifier, if any.
+ /// Retrieve the location of the 'const' qualifier, if any.
SourceLocation getConstQualifierLoc() const {
return SourceLocation::getFromRawEncoding(ConstQualifierLoc);
}
- /// \brief Retrieve the location of the 'volatile' qualifier, if any.
+ /// Retrieve the location of the 'volatile' qualifier, if any.
SourceLocation getVolatileQualifierLoc() const {
return SourceLocation::getFromRawEncoding(VolatileQualifierLoc);
}
- /// \brief Retrieve the location of the 'restrict' qualifier, if any.
+ /// Retrieve the location of the 'restrict' qualifier, if any.
SourceLocation getRestrictQualifierLoc() const {
return SourceLocation::getFromRawEncoding(RestrictQualifierLoc);
}
- /// \brief Retrieve the location of the 'mutable' qualifier, if any.
+ /// Retrieve the location of the 'mutable' qualifier, if any.
SourceLocation getMutableLoc() const {
return SourceLocation::getFromRawEncoding(MutableLoc);
}
- /// \brief Determine whether this function declaration contains a
+ /// Determine whether this function declaration contains a
/// ref-qualifier.
bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); }
- /// \brief Determine whether this lambda-declarator contains a 'mutable'
+ /// Determine whether this lambda-declarator contains a 'mutable'
/// qualifier.
bool hasMutableQualifier() const { return getMutableLoc().isValid(); }
- /// \brief Get the type of exception specification this function has.
+ /// Get the type of exception specification this function has.
ExceptionSpecificationType getExceptionSpecType() const {
return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
}
- /// \brief Get the number of dynamic exception specifications.
+ /// Get the number of dynamic exception specifications.
unsigned getNumExceptions() const {
assert(ExceptionSpecType != EST_None);
return NumExceptionsOrDecls;
}
- /// \brief Get the non-parameter decls defined within this function
+ /// Get the non-parameter decls defined within this function
/// prototype. Typically these are tag declarations.
ArrayRef<NamedDecl *> getDeclsInPrototype() const {
assert(ExceptionSpecType == EST_None);
return llvm::makeArrayRef(DeclsInPrototype, NumExceptionsOrDecls);
}
- /// \brief Determine whether this function declarator had a
+ /// Determine whether this function declarator had a
/// trailing-return-type.
bool hasTrailingReturnType() const { return HasTrailingReturnType; }
- /// \brief Get the trailing-return-type for this function declarator.
+ /// Get the trailing-return-type for this function declarator.
ParsedType getTrailingReturnType() const { return TrailingReturnType; }
};
- struct BlockPointerTypeInfo : TypeInfoCommon {
+ struct BlockPointerTypeInfo {
/// For now, sema will catch these as invalid.
/// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic.
unsigned TypeQuals : 5;
@@ -1458,7 +1469,7 @@ struct DeclaratorChunk {
}
};
- struct MemberPointerTypeInfo : TypeInfoCommon {
+ struct MemberPointerTypeInfo {
/// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic.
unsigned TypeQuals : 5;
// CXXScopeSpec has a constructor, so it can't be a direct member.
@@ -1475,15 +1486,14 @@ struct DeclaratorChunk {
}
};
- struct PipeTypeInfo : TypeInfoCommon {
- /// The access writes.
- unsigned AccessWrites : 3;
+ struct PipeTypeInfo {
+ /// The access writes.
+ unsigned AccessWrites : 3;
- void destroy() {}
+ void destroy() {}
};
union {
- TypeInfoCommon Common;
PointerTypeInfo Ptr;
ReferenceTypeInfo Ref;
ArrayTypeInfo Arr;
@@ -1506,17 +1516,12 @@ struct DeclaratorChunk {
}
}
- /// \brief If there are attributes applied to this declaratorchunk, return
+ /// If there are attributes applied to this declaratorchunk, return
/// them.
- const AttributeList *getAttrs() const {
- return Common.AttrList;
- }
+ const ParsedAttributesView &getAttrs() const { return AttrList; }
+ ParsedAttributesView &getAttrs() { return AttrList; }
- AttributeList *&getAttrListRef() {
- return Common.AttrList;
- }
-
- /// \brief Return a DeclaratorChunk for a pointer.
+ /// Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
SourceLocation ConstQualLoc,
SourceLocation VolatileQualLoc,
@@ -1532,11 +1537,10 @@ struct DeclaratorChunk {
I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding();
I.Ptr.AtomicQualLoc = AtomicQualLoc.getRawEncoding();
I.Ptr.UnalignedQualLoc = UnalignedQualLoc.getRawEncoding();
- I.Ptr.AttrList = nullptr;
return I;
}
- /// \brief Return a DeclaratorChunk for a reference.
+ /// Return a DeclaratorChunk for a reference.
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
bool lvalue) {
DeclaratorChunk I;
@@ -1544,11 +1548,10 @@ struct DeclaratorChunk {
I.Loc = Loc;
I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
I.Ref.LValueRef = lvalue;
- I.Ref.AttrList = nullptr;
return I;
}
- /// \brief Return a DeclaratorChunk for an array.
+ /// Return a DeclaratorChunk for an array.
static DeclaratorChunk getArray(unsigned TypeQuals,
bool isStatic, bool isStar, Expr *NumElts,
SourceLocation LBLoc, SourceLocation RBLoc) {
@@ -1556,7 +1559,6 @@ struct DeclaratorChunk {
I.Kind = Array;
I.Loc = LBLoc;
I.EndLoc = RBLoc;
- I.Arr.AttrList = nullptr;
I.Arr.TypeQuals = TypeQuals;
I.Arr.hasStatic = isStatic;
I.Arr.isStar = isStar;
@@ -1593,25 +1595,23 @@ struct DeclaratorChunk {
TypeResult TrailingReturnType =
TypeResult());
- /// \brief Return a DeclaratorChunk for a block.
+ /// Return a DeclaratorChunk for a block.
static DeclaratorChunk getBlockPointer(unsigned TypeQuals,
SourceLocation Loc) {
DeclaratorChunk I;
I.Kind = BlockPointer;
I.Loc = Loc;
I.Cls.TypeQuals = TypeQuals;
- I.Cls.AttrList = nullptr;
return I;
}
- /// \brief Return a DeclaratorChunk for a block.
+ /// Return a DeclaratorChunk for a block.
static DeclaratorChunk getPipe(unsigned TypeQuals,
SourceLocation Loc) {
DeclaratorChunk I;
I.Kind = Pipe;
I.Loc = Loc;
I.Cls.TypeQuals = TypeQuals;
- I.Cls.AttrList = nullptr;
return I;
}
@@ -1623,19 +1623,17 @@ struct DeclaratorChunk {
I.Loc = SS.getBeginLoc();
I.EndLoc = Loc;
I.Mem.TypeQuals = TypeQuals;
- I.Mem.AttrList = nullptr;
new (I.Mem.ScopeMem) CXXScopeSpec(SS);
return I;
}
- /// \brief Return a DeclaratorChunk for a paren.
+ /// Return a DeclaratorChunk for a paren.
static DeclaratorChunk getParen(SourceLocation LParenLoc,
SourceLocation RParenLoc) {
DeclaratorChunk I;
I.Kind = Paren;
I.Loc = LParenLoc;
I.EndLoc = RParenLoc;
- I.Common.AttrList = nullptr;
return I;
}
@@ -1696,7 +1694,7 @@ public:
}
};
-/// \brief Described the kind of function definition (if any) provided for
+/// Described the kind of function definition (if any) provided for
/// a function.
enum FunctionDefinitionKind {
FDK_Declaration,
@@ -1705,21 +1703,7 @@ enum FunctionDefinitionKind {
FDK_Deleted
};
-/// \brief Information about one declarator, including the parsed type
-/// information and the identifier.
-///
-/// When the declarator is fully formed, this is turned into the appropriate
-/// Decl object.
-///
-/// Declarators come in two types: normal declarators and abstract declarators.
-/// Abstract declarators are used when parsing types, and don't have an
-/// identifier. Normal declarators do have ID's.
-///
-/// Instances of this class should be a transient object that lives on the
-/// stack, not objects that are allocated in large quantities on the heap.
-class Declarator {
-public:
- enum TheContext {
+enum class DeclaratorContext {
FileContext, // File scope declaration.
PrototypeContext, // Within a function prototype.
ObjCResultContext, // An ObjC method result type.
@@ -1741,19 +1725,36 @@ public:
LambdaExprParameterContext, // Lambda-expression parameter declarator.
ConversionIdContext, // C++ conversion-type-id.
TrailingReturnContext, // C++11 trailing-type-specifier.
- TemplateTypeArgContext, // Template type argument.
+ TrailingReturnVarContext, // C++11 trailing-type-specifier for variable.
+ TemplateArgContext, // Any template argument (in template argument list).
+ TemplateTypeArgContext, // Template type argument (in default argument).
AliasDeclContext, // C++11 alias-declaration.
AliasTemplateContext // C++11 alias-declaration template.
- };
+};
+
+/// Information about one declarator, including the parsed type
+/// information and the identifier.
+///
+/// When the declarator is fully formed, this is turned into the appropriate
+/// Decl object.
+///
+/// Declarators come in two types: normal declarators and abstract declarators.
+/// Abstract declarators are used when parsing types, and don't have an
+/// identifier. Normal declarators do have ID's.
+///
+/// Instances of this class should be a transient object that lives on the
+/// stack, not objects that are allocated in large quantities on the heap.
+class Declarator {
+
private:
const DeclSpec &DS;
CXXScopeSpec SS;
UnqualifiedId Name;
SourceRange Range;
- /// \brief Where we are parsing this declarator.
- TheContext Context;
+ /// Where we are parsing this declarator.
+ DeclaratorContext Context;
/// The C++17 structured binding, if any. This is an alternative to a Name.
DecompositionDeclarator BindingGroup;
@@ -1776,10 +1777,10 @@ private:
/// Actually a FunctionDefinitionKind.
unsigned FunctionDefinition : 2;
- /// \brief Is this Declarator a redeclaration?
+ /// Is this Declarator a redeclaration?
unsigned Redeclaration : 1;
- /// \brief true if the declaration is preceded by \c __extension__.
+ /// true if the declaration is preceded by \c __extension__.
unsigned Extension : 1;
/// Indicates whether this is an Objective-C instance variable.
@@ -1794,7 +1795,7 @@ private:
/// Attrs - Attributes.
ParsedAttributes Attrs;
- /// \brief The asm label, if specified.
+ /// The asm label, if specified.
Expr *AsmLabel;
#ifndef _MSC_VER
@@ -1809,18 +1810,18 @@ private:
};
#endif
- /// \brief If this is the second or subsequent declarator in this declaration,
+ /// If this is the second or subsequent declarator in this declaration,
/// the location of the comma before this declarator.
SourceLocation CommaLoc;
- /// \brief If provided, the source location of the ellipsis used to describe
+ /// If provided, the source location of the ellipsis used to describe
/// this declarator as a parameter pack.
SourceLocation EllipsisLoc;
friend struct DeclaratorChunk;
public:
- Declarator(const DeclSpec &ds, TheContext C)
+ Declarator(const DeclSpec &ds, DeclaratorContext C)
: DS(ds), Range(ds.getSourceRange()), Context(C),
InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
GroupingParens(false), FunctionDefinition(FDK_Declaration),
@@ -1851,23 +1852,23 @@ public:
const CXXScopeSpec &getCXXScopeSpec() const { return SS; }
CXXScopeSpec &getCXXScopeSpec() { return SS; }
- /// \brief Retrieve the name specified by this declarator.
+ /// Retrieve the name specified by this declarator.
UnqualifiedId &getName() { return Name; }
const DecompositionDeclarator &getDecompositionDeclarator() const {
return BindingGroup;
}
- TheContext getContext() const { return Context; }
+ DeclaratorContext getContext() const { return Context; }
bool isPrototypeContext() const {
- return (Context == PrototypeContext ||
- Context == ObjCParameterContext ||
- Context == ObjCResultContext ||
- Context == LambdaExprParameterContext);
+ return (Context == DeclaratorContext::PrototypeContext ||
+ Context == DeclaratorContext::ObjCParameterContext ||
+ Context == DeclaratorContext::ObjCResultContext ||
+ Context == DeclaratorContext::LambdaExprParameterContext);
}
- /// \brief Get the source range that spans this declarator.
+ /// Get the source range that spans this declarator.
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
@@ -1895,7 +1896,7 @@ public:
Range.setEnd(SR.getEnd());
}
- /// \brief Reset the contents of this Declarator.
+ /// Reset the contents of this Declarator.
void clear() {
SS.clear();
Name.clear();
@@ -1919,32 +1920,34 @@ public:
/// parameter lists.
bool mayOmitIdentifier() const {
switch (Context) {
- case FileContext:
- case KNRTypeListContext:
- case MemberContext:
- case BlockContext:
- case ForContext:
- case InitStmtContext:
- case ConditionContext:
+ case DeclaratorContext::FileContext:
+ case DeclaratorContext::KNRTypeListContext:
+ case DeclaratorContext::MemberContext:
+ case DeclaratorContext::BlockContext:
+ case DeclaratorContext::ForContext:
+ case DeclaratorContext::InitStmtContext:
+ case DeclaratorContext::ConditionContext:
return false;
- case TypeNameContext:
- case FunctionalCastContext:
- case AliasDeclContext:
- case AliasTemplateContext:
- case PrototypeContext:
- case LambdaExprParameterContext:
- case ObjCParameterContext:
- case ObjCResultContext:
- case TemplateParamContext:
- case CXXNewContext:
- case CXXCatchContext:
- case ObjCCatchContext:
- case BlockLiteralContext:
- case LambdaExprContext:
- case ConversionIdContext:
- case TemplateTypeArgContext:
- case TrailingReturnContext:
+ case DeclaratorContext::TypeNameContext:
+ case DeclaratorContext::FunctionalCastContext:
+ case DeclaratorContext::AliasDeclContext:
+ case DeclaratorContext::AliasTemplateContext:
+ case DeclaratorContext::PrototypeContext:
+ case DeclaratorContext::LambdaExprParameterContext:
+ case DeclaratorContext::ObjCParameterContext:
+ case DeclaratorContext::ObjCResultContext:
+ case DeclaratorContext::TemplateParamContext:
+ case DeclaratorContext::CXXNewContext:
+ case DeclaratorContext::CXXCatchContext:
+ case DeclaratorContext::ObjCCatchContext:
+ case DeclaratorContext::BlockLiteralContext:
+ case DeclaratorContext::LambdaExprContext:
+ case DeclaratorContext::ConversionIdContext:
+ case DeclaratorContext::TemplateArgContext:
+ case DeclaratorContext::TemplateTypeArgContext:
+ case DeclaratorContext::TrailingReturnContext:
+ case DeclaratorContext::TrailingReturnVarContext:
return true;
}
llvm_unreachable("unknown context kind!");
@@ -1955,32 +1958,34 @@ public:
/// typenames.
bool mayHaveIdentifier() const {
switch (Context) {
- case FileContext:
- case KNRTypeListContext:
- case MemberContext:
- case BlockContext:
- case ForContext:
- case InitStmtContext:
- case ConditionContext:
- case PrototypeContext:
- case LambdaExprParameterContext:
- case TemplateParamContext:
- case CXXCatchContext:
- case ObjCCatchContext:
+ case DeclaratorContext::FileContext:
+ case DeclaratorContext::KNRTypeListContext:
+ case DeclaratorContext::MemberContext:
+ case DeclaratorContext::BlockContext:
+ case DeclaratorContext::ForContext:
+ case DeclaratorContext::InitStmtContext:
+ case DeclaratorContext::ConditionContext:
+ case DeclaratorContext::PrototypeContext:
+ case DeclaratorContext::LambdaExprParameterContext:
+ case DeclaratorContext::TemplateParamContext:
+ case DeclaratorContext::CXXCatchContext:
+ case DeclaratorContext::ObjCCatchContext:
return true;
- case TypeNameContext:
- case FunctionalCastContext:
- case CXXNewContext:
- case AliasDeclContext:
- case AliasTemplateContext:
- case ObjCParameterContext:
- case ObjCResultContext:
- case BlockLiteralContext:
- case LambdaExprContext:
- case ConversionIdContext:
- case TemplateTypeArgContext:
- case TrailingReturnContext:
+ case DeclaratorContext::TypeNameContext:
+ case DeclaratorContext::FunctionalCastContext:
+ case DeclaratorContext::CXXNewContext:
+ case DeclaratorContext::AliasDeclContext:
+ case DeclaratorContext::AliasTemplateContext:
+ case DeclaratorContext::ObjCParameterContext:
+ case DeclaratorContext::ObjCResultContext:
+ case DeclaratorContext::BlockLiteralContext:
+ case DeclaratorContext::LambdaExprContext:
+ case DeclaratorContext::ConversionIdContext:
+ case DeclaratorContext::TemplateArgContext:
+ case DeclaratorContext::TemplateTypeArgContext:
+ case DeclaratorContext::TrailingReturnContext:
+ case DeclaratorContext::TrailingReturnVarContext:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -1989,38 +1994,40 @@ public:
/// Return true if the context permits a C++17 decomposition declarator.
bool mayHaveDecompositionDeclarator() const {
switch (Context) {
- case FileContext:
+ case DeclaratorContext::FileContext:
// FIXME: It's not clear that the proposal meant to allow file-scope
// structured bindings, but it does.
- case BlockContext:
- case ForContext:
- case InitStmtContext:
- case ConditionContext:
+ case DeclaratorContext::BlockContext:
+ case DeclaratorContext::ForContext:
+ case DeclaratorContext::InitStmtContext:
+ case DeclaratorContext::ConditionContext:
return true;
- case MemberContext:
- case PrototypeContext:
- case TemplateParamContext:
+ case DeclaratorContext::MemberContext:
+ case DeclaratorContext::PrototypeContext:
+ case DeclaratorContext::TemplateParamContext:
// Maybe one day...
return false;
// These contexts don't allow any kind of non-abstract declarator.
- case KNRTypeListContext:
- case TypeNameContext:
- case FunctionalCastContext:
- case AliasDeclContext:
- case AliasTemplateContext:
- case LambdaExprParameterContext:
- case ObjCParameterContext:
- case ObjCResultContext:
- case CXXNewContext:
- case CXXCatchContext:
- case ObjCCatchContext:
- case BlockLiteralContext:
- case LambdaExprContext:
- case ConversionIdContext:
- case TemplateTypeArgContext:
- case TrailingReturnContext:
+ case DeclaratorContext::KNRTypeListContext:
+ case DeclaratorContext::TypeNameContext:
+ case DeclaratorContext::FunctionalCastContext:
+ case DeclaratorContext::AliasDeclContext:
+ case DeclaratorContext::AliasTemplateContext:
+ case DeclaratorContext::LambdaExprParameterContext:
+ case DeclaratorContext::ObjCParameterContext:
+ case DeclaratorContext::ObjCResultContext:
+ case DeclaratorContext::CXXNewContext:
+ case DeclaratorContext::CXXCatchContext:
+ case DeclaratorContext::ObjCCatchContext:
+ case DeclaratorContext::BlockLiteralContext:
+ case DeclaratorContext::LambdaExprContext:
+ case DeclaratorContext::ConversionIdContext:
+ case DeclaratorContext::TemplateArgContext:
+ case DeclaratorContext::TemplateTypeArgContext:
+ case DeclaratorContext::TrailingReturnContext:
+ case DeclaratorContext::TrailingReturnVarContext:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2035,45 +2042,47 @@ public:
return false;
if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern &&
- Context != FileContext)
+ Context != DeclaratorContext::FileContext)
return false;
// Special names can't have direct initializers.
- if (Name.getKind() != UnqualifiedId::IK_Identifier)
+ if (Name.getKind() != UnqualifiedIdKind::IK_Identifier)
return false;
switch (Context) {
- case FileContext:
- case BlockContext:
- case ForContext:
- case InitStmtContext:
+ case DeclaratorContext::FileContext:
+ case DeclaratorContext::BlockContext:
+ case DeclaratorContext::ForContext:
+ case DeclaratorContext::InitStmtContext:
+ case DeclaratorContext::TrailingReturnVarContext:
return true;
- case ConditionContext:
+ case DeclaratorContext::ConditionContext:
// This may not be followed by a direct initializer, but it can't be a
// function declaration either, and we'd prefer to perform a tentative
// parse in order to produce the right diagnostic.
return true;
- case KNRTypeListContext:
- case MemberContext:
- case PrototypeContext:
- case LambdaExprParameterContext:
- case ObjCParameterContext:
- case ObjCResultContext:
- case TemplateParamContext:
- case CXXCatchContext:
- case ObjCCatchContext:
- case TypeNameContext:
- case FunctionalCastContext: // FIXME
- case CXXNewContext:
- case AliasDeclContext:
- case AliasTemplateContext:
- case BlockLiteralContext:
- case LambdaExprContext:
- case ConversionIdContext:
- case TemplateTypeArgContext:
- case TrailingReturnContext:
+ case DeclaratorContext::KNRTypeListContext:
+ case DeclaratorContext::MemberContext:
+ case DeclaratorContext::PrototypeContext:
+ case DeclaratorContext::LambdaExprParameterContext:
+ case DeclaratorContext::ObjCParameterContext:
+ case DeclaratorContext::ObjCResultContext:
+ case DeclaratorContext::TemplateParamContext:
+ case DeclaratorContext::CXXCatchContext:
+ case DeclaratorContext::ObjCCatchContext:
+ case DeclaratorContext::TypeNameContext:
+ case DeclaratorContext::FunctionalCastContext: // FIXME
+ case DeclaratorContext::CXXNewContext:
+ case DeclaratorContext::AliasDeclContext:
+ case DeclaratorContext::AliasTemplateContext:
+ case DeclaratorContext::BlockLiteralContext:
+ case DeclaratorContext::LambdaExprContext:
+ case DeclaratorContext::ConversionIdContext:
+ case DeclaratorContext::TemplateArgContext:
+ case DeclaratorContext::TemplateTypeArgContext:
+ case DeclaratorContext::TrailingReturnContext:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2089,8 +2098,8 @@ public:
/// special C++ name (constructor, destructor, etc.), or a structured
/// binding (which is not exactly a name, but occupies the same position).
bool hasName() const {
- return Name.getKind() != UnqualifiedId::IK_Identifier || Name.Identifier ||
- isDecompositionDeclarator();
+ return Name.getKind() != UnqualifiedIdKind::IK_Identifier ||
+ Name.Identifier || isDecompositionDeclarator();
}
/// Return whether this declarator is a decomposition declarator.
@@ -2099,14 +2108,14 @@ public:
}
IdentifierInfo *getIdentifier() const {
- if (Name.getKind() == UnqualifiedId::IK_Identifier)
+ if (Name.getKind() == UnqualifiedIdKind::IK_Identifier)
return Name.Identifier;
return nullptr;
}
SourceLocation getIdentifierLoc() const { return Name.StartLocation; }
- /// \brief Set the name of this declarator to be the given identifier.
+ /// Set the name of this declarator to be the given identifier.
void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc) {
Name.setIdentifier(Id, IdLoc);
}
@@ -2119,23 +2128,33 @@ public:
/// AddTypeInfo - Add a chunk to this declarator. Also extend the range to
/// EndLoc, which should be the last token of the chunk.
- void AddTypeInfo(const DeclaratorChunk &TI,
- ParsedAttributes &attrs,
+ /// This function takes attrs by R-Value reference because it takes ownership
+ /// of those attributes from the parameter.
+ void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs,
SourceLocation EndLoc) {
DeclTypeInfo.push_back(TI);
- DeclTypeInfo.back().getAttrListRef() = attrs.getList();
+ DeclTypeInfo.back().getAttrs().addAll(attrs.begin(), attrs.end());
getAttributePool().takeAllFrom(attrs.getPool());
if (!EndLoc.isInvalid())
SetRangeEnd(EndLoc);
}
- /// \brief Add a new innermost chunk to this declarator.
+ /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to
+ /// EndLoc, which should be the last token of the chunk.
+ void AddTypeInfo(const DeclaratorChunk &TI, SourceLocation EndLoc) {
+ DeclTypeInfo.push_back(TI);
+
+ if (!EndLoc.isInvalid())
+ SetRangeEnd(EndLoc);
+ }
+
+ /// Add a new innermost chunk to this declarator.
void AddInnermostTypeInfo(const DeclaratorChunk &TI) {
DeclTypeInfo.insert(DeclTypeInfo.begin(), TI);
}
- /// \brief Return the number of types applied to this declarator.
+ /// Return the number of types applied to this declarator.
unsigned getNumTypeObjects() const { return DeclTypeInfo.size(); }
/// Return the specified TypeInfo from this declarator. TypeInfo #0 is
@@ -2242,7 +2261,7 @@ public:
return const_cast<Declarator*>(this)->getFunctionTypeInfo();
}
- /// \brief Determine whether the declaration that will be produced from
+ /// Determine whether the declaration that will be produced from
/// this declaration will be a function.
///
/// A declaration can declare a function even if the declarator itself
@@ -2250,39 +2269,41 @@ public:
/// type. This routine checks for both cases.
bool isDeclarationOfFunction() const;
- /// \brief Return true if this declaration appears in a context where a
+ /// Return true if this declaration appears in a context where a
/// function declarator would be a function declaration.
bool isFunctionDeclarationContext() const {
if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
return false;
switch (Context) {
- case FileContext:
- case MemberContext:
- case BlockContext:
- case ForContext:
- case InitStmtContext:
+ case DeclaratorContext::FileContext:
+ case DeclaratorContext::MemberContext:
+ case DeclaratorContext::BlockContext:
+ case DeclaratorContext::ForContext:
+ case DeclaratorContext::InitStmtContext:
return true;
- case ConditionContext:
- case KNRTypeListContext:
- case TypeNameContext:
- case FunctionalCastContext:
- case AliasDeclContext:
- case AliasTemplateContext:
- case PrototypeContext:
- case LambdaExprParameterContext:
- case ObjCParameterContext:
- case ObjCResultContext:
- case TemplateParamContext:
- case CXXNewContext:
- case CXXCatchContext:
- case ObjCCatchContext:
- case BlockLiteralContext:
- case LambdaExprContext:
- case ConversionIdContext:
- case TemplateTypeArgContext:
- case TrailingReturnContext:
+ case DeclaratorContext::ConditionContext:
+ case DeclaratorContext::KNRTypeListContext:
+ case DeclaratorContext::TypeNameContext:
+ case DeclaratorContext::FunctionalCastContext:
+ case DeclaratorContext::AliasDeclContext:
+ case DeclaratorContext::AliasTemplateContext:
+ case DeclaratorContext::PrototypeContext:
+ case DeclaratorContext::LambdaExprParameterContext:
+ case DeclaratorContext::ObjCParameterContext:
+ case DeclaratorContext::ObjCResultContext:
+ case DeclaratorContext::TemplateParamContext:
+ case DeclaratorContext::CXXNewContext:
+ case DeclaratorContext::CXXCatchContext:
+ case DeclaratorContext::ObjCCatchContext:
+ case DeclaratorContext::BlockLiteralContext:
+ case DeclaratorContext::LambdaExprContext:
+ case DeclaratorContext::ConversionIdContext:
+ case DeclaratorContext::TemplateArgContext:
+ case DeclaratorContext::TemplateTypeArgContext:
+ case DeclaratorContext::TrailingReturnContext:
+ case DeclaratorContext::TrailingReturnVarContext:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2292,39 +2313,44 @@ public:
/// expression could appear.
bool isExpressionContext() const {
switch (Context) {
- case FileContext:
- case KNRTypeListContext:
- case MemberContext:
- case TypeNameContext: // FIXME: sizeof(...) permits an expression.
- case FunctionalCastContext:
- case AliasDeclContext:
- case AliasTemplateContext:
- case PrototypeContext:
- case LambdaExprParameterContext:
- case ObjCParameterContext:
- case ObjCResultContext:
- case TemplateParamContext:
- case CXXNewContext:
- case CXXCatchContext:
- case ObjCCatchContext:
- case BlockLiteralContext:
- case LambdaExprContext:
- case ConversionIdContext:
- case TrailingReturnContext:
+ case DeclaratorContext::FileContext:
+ case DeclaratorContext::KNRTypeListContext:
+ case DeclaratorContext::MemberContext:
+
+ // FIXME: sizeof(...) permits an expression.
+ case DeclaratorContext::TypeNameContext:
+
+ case DeclaratorContext::FunctionalCastContext:
+ case DeclaratorContext::AliasDeclContext:
+ case DeclaratorContext::AliasTemplateContext:
+ case DeclaratorContext::PrototypeContext:
+ case DeclaratorContext::LambdaExprParameterContext:
+ case DeclaratorContext::ObjCParameterContext:
+ case DeclaratorContext::ObjCResultContext:
+ case DeclaratorContext::TemplateParamContext:
+ case DeclaratorContext::CXXNewContext:
+ case DeclaratorContext::CXXCatchContext:
+ case DeclaratorContext::ObjCCatchContext:
+ case DeclaratorContext::BlockLiteralContext:
+ case DeclaratorContext::LambdaExprContext:
+ case DeclaratorContext::ConversionIdContext:
+ case DeclaratorContext::TrailingReturnContext:
+ case DeclaratorContext::TrailingReturnVarContext:
+ case DeclaratorContext::TemplateTypeArgContext:
return false;
- case BlockContext:
- case ForContext:
- case InitStmtContext:
- case ConditionContext:
- case TemplateTypeArgContext:
+ case DeclaratorContext::BlockContext:
+ case DeclaratorContext::ForContext:
+ case DeclaratorContext::InitStmtContext:
+ case DeclaratorContext::ConditionContext:
+ case DeclaratorContext::TemplateArgContext:
return true;
}
llvm_unreachable("unknown context kind!");
}
- /// \brief Return true if a function declarator at this position would be a
+ /// Return true if a function declarator at this position would be a
/// function declaration.
bool isFunctionDeclaratorAFunctionDeclaration() const {
if (!isFunctionDeclarationContext())
@@ -2337,7 +2363,7 @@ public:
return true;
}
- /// \brief Determine whether a trailing return type was written (at any
+ /// Determine whether a trailing return type was written (at any
/// level) within this declarator.
bool hasTrailingReturnType() const {
for (const auto &Chunk : type_objects())
@@ -2363,29 +2389,25 @@ public:
SetRangeEnd(lastLoc);
}
- const AttributeList *getAttributes() const { return Attrs.getList(); }
- AttributeList *getAttributes() { return Attrs.getList(); }
-
- AttributeList *&getAttrListRef() { return Attrs.getListRef(); }
+ const ParsedAttributes &getAttributes() const { return Attrs; }
+ ParsedAttributes &getAttributes() { return Attrs; }
/// hasAttributes - do we contain any attributes?
bool hasAttributes() const {
- if (getAttributes() || getDeclSpec().hasAttributes()) return true;
+ if (!getAttributes().empty() || getDeclSpec().hasAttributes())
+ return true;
for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i)
- if (getTypeObject(i).getAttrs())
+ if (!getTypeObject(i).getAttrs().empty())
return true;
return false;
}
- /// \brief Return a source range list of C++11 attributes associated
+ /// Return a source range list of C++11 attributes associated
/// with the declarator.
void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) {
- AttributeList *AttrList = Attrs.getList();
- while (AttrList) {
- if (AttrList->isCXX11Attribute())
- Ranges.push_back(AttrList->getRange());
- AttrList = AttrList->getNext();
- }
+ for (const ParsedAttr &AL : Attrs)
+ if (AL.isCXX11Attribute())
+ Ranges.push_back(AL.getRange());
}
void setAsmLabel(Expr *E) { AsmLabel = E; }
@@ -2430,7 +2452,8 @@ public:
/// Returns true if this declares a real member and not a friend.
bool isFirstDeclarationOfMember() {
- return getContext() == MemberContext && !getDeclSpec().isFriendSpecified();
+ return getContext() == DeclaratorContext::MemberContext &&
+ !getDeclSpec().isFriendSpecified();
}
/// Returns true if this declares a static member. This cannot be called on a
@@ -2445,16 +2468,17 @@ public:
bool isRedeclaration() const { return Redeclaration; }
};
-/// \brief This little struct is used to capture information about
+/// This little struct is used to capture information about
/// structure field declarators, which is basically just a bitfield size.
struct FieldDeclarator {
Declarator D;
Expr *BitfieldSize;
explicit FieldDeclarator(const DeclSpec &DS)
- : D(DS, Declarator::MemberContext), BitfieldSize(nullptr) { }
+ : D(DS, DeclaratorContext::MemberContext),
+ BitfieldSize(nullptr) {}
};
-/// \brief Represents a C++11 virt-specifier-seq.
+/// Represents a C++11 virt-specifier-seq.
class VirtSpecifiers {
public:
enum Specifier {
@@ -2504,9 +2528,9 @@ enum class LambdaCaptureInitKind {
ListInit //!< [a{b}]
};
-/// \brief Represents a complete lambda introducer.
+/// Represents a complete lambda introducer.
struct LambdaIntroducer {
- /// \brief An individual capture in a lambda introducer.
+ /// An individual capture in a lambda introducer.
struct LambdaCapture {
LambdaCaptureKind Kind;
SourceLocation Loc;
@@ -2515,12 +2539,16 @@ struct LambdaIntroducer {
LambdaCaptureInitKind InitKind;
ExprResult Init;
ParsedType InitCaptureType;
+ SourceRange ExplicitRange;
+
LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc,
IdentifierInfo *Id, SourceLocation EllipsisLoc,
LambdaCaptureInitKind InitKind, ExprResult Init,
- ParsedType InitCaptureType)
+ ParsedType InitCaptureType,
+ SourceRange ExplicitRange)
: Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc),
- InitKind(InitKind), Init(Init), InitCaptureType(InitCaptureType) {}
+ InitKind(InitKind), Init(Init), InitCaptureType(InitCaptureType),
+ ExplicitRange(ExplicitRange) {}
};
SourceRange Range;
@@ -2531,16 +2559,17 @@ struct LambdaIntroducer {
LambdaIntroducer()
: Default(LCD_None) {}
- /// \brief Append a capture in a lambda introducer.
+ /// Append a capture in a lambda introducer.
void addCapture(LambdaCaptureKind Kind,
SourceLocation Loc,
IdentifierInfo* Id,
SourceLocation EllipsisLoc,
LambdaCaptureInitKind InitKind,
ExprResult Init,
- ParsedType InitCaptureType) {
+ ParsedType InitCaptureType,
+ SourceRange ExplicitRange) {
Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init,
- InitCaptureType));
+ InitCaptureType, ExplicitRange));
}
};
diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h
index d65dbf0cd34e0..76aa4546d749a 100644
--- a/include/clang/Sema/DelayedDiagnostic.h
+++ b/include/clang/Sema/DelayedDiagnostic.h
@@ -1,4 +1,4 @@
-//===--- DelayedDiagnostic.h - Delayed declarator diagnostics ---*- C++ -*-===//
+//===- DelayedDiagnostic.h - Delayed declarator diagnostics -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,9 +6,9 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
-/// \brief Defines the classes clang::DelayedDiagnostic and
+/// Defines the classes clang::DelayedDiagnostic and
/// clang::AccessedEntity.
///
/// DelayedDiangostic is used to record diagnostics that are being
@@ -16,15 +16,34 @@
/// diagnostics -- notably deprecation and access control -- are suppressed
/// based on semantic properties of the parsed declaration that aren't known
/// until it is fully parsed.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H
#define LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H
+#include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Sema.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
+#include <cstddef>
+#include <utility>
namespace clang {
+
+class ObjCInterfaceDecl;
+class ObjCPropertyDecl;
+
namespace sema {
/// A declaration being accessed, together with information about how
@@ -39,16 +58,14 @@ public:
/// The target is the base class.
enum BaseNonce { Base };
- bool isMemberAccess() const { return IsMember; }
-
AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
MemberNonce _,
CXXRecordDecl *NamingClass,
DeclAccessPair FoundDecl,
QualType BaseObjectType)
- : Access(FoundDecl.getAccess()), IsMember(true),
- Target(FoundDecl.getDecl()), NamingClass(NamingClass),
- BaseObjectType(BaseObjectType), Diag(0, Allocator) {
+ : Access(FoundDecl.getAccess()), IsMember(true),
+ Target(FoundDecl.getDecl()), NamingClass(NamingClass),
+ BaseObjectType(BaseObjectType), Diag(0, Allocator) {
}
AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
@@ -56,11 +73,10 @@ public:
CXXRecordDecl *BaseClass,
CXXRecordDecl *DerivedClass,
AccessSpecifier Access)
- : Access(Access), IsMember(false),
- Target(BaseClass),
- NamingClass(DerivedClass),
- Diag(0, Allocator) {
- }
+ : Access(Access), IsMember(false), Target(BaseClass),
+ NamingClass(DerivedClass), Diag(0, Allocator) {}
+
+ bool isMemberAccess() const { return IsMember; }
bool isQuiet() const { return Diag.getDiagID() == 0; }
@@ -123,7 +139,7 @@ public:
void Destroy();
static DelayedDiagnostic makeAvailability(AvailabilityResult AR,
- SourceLocation Loc,
+ ArrayRef<SourceLocation> Locs,
const NamedDecl *ReferringDecl,
const NamedDecl *OffendingDecl,
const ObjCInterfaceDecl *UnknownObjCClass,
@@ -131,7 +147,6 @@ public:
StringRef Msg,
bool ObjCPropertyAccess);
-
static DelayedDiagnostic makeAccess(SourceLocation Loc,
const AccessedEntity &Entity) {
DelayedDiagnostic DD;
@@ -179,6 +194,12 @@ public:
return StringRef(AvailabilityData.Message, AvailabilityData.MessageLen);
}
+ ArrayRef<SourceLocation> getAvailabilitySelectorLocs() const {
+ assert(Kind == Availability && "Not an availability diagnostic.");
+ return llvm::makeArrayRef(AvailabilityData.SelectorLocs,
+ AvailabilityData.NumSelectorLocs);
+ }
+
AvailabilityResult getAvailabilityResult() const {
assert(Kind == Availability && "Not an availability diagnostic.");
return AvailabilityData.AR;
@@ -216,7 +237,6 @@ public:
}
private:
-
struct AD {
const NamedDecl *ReferringDecl;
const NamedDecl *OffendingDecl;
@@ -224,6 +244,8 @@ private:
const ObjCPropertyDecl *ObjCProperty;
const char *Message;
size_t MessageLen;
+ SourceLocation *SelectorLocs;
+ size_t NumSelectorLocs;
AvailabilityResult AR;
bool ObjCPropertyAccess;
};
@@ -243,25 +265,22 @@ private:
};
};
-/// \brief A collection of diagnostics which were delayed.
+/// A collection of diagnostics which were delayed.
class DelayedDiagnosticPool {
const DelayedDiagnosticPool *Parent;
SmallVector<DelayedDiagnostic, 4> Diagnostics;
- DelayedDiagnosticPool(const DelayedDiagnosticPool &) = delete;
- void operator=(const DelayedDiagnosticPool &) = delete;
public:
DelayedDiagnosticPool(const DelayedDiagnosticPool *parent) : Parent(parent) {}
- ~DelayedDiagnosticPool() {
- for (SmallVectorImpl<DelayedDiagnostic>::iterator
- i = Diagnostics.begin(), e = Diagnostics.end(); i != e; ++i)
- i->Destroy();
- }
+
+ DelayedDiagnosticPool(const DelayedDiagnosticPool &) = delete;
+ DelayedDiagnosticPool &operator=(const DelayedDiagnosticPool &) = delete;
DelayedDiagnosticPool(DelayedDiagnosticPool &&Other)
- : Parent(Other.Parent), Diagnostics(std::move(Other.Diagnostics)) {
+ : Parent(Other.Parent), Diagnostics(std::move(Other.Diagnostics)) {
Other.Diagnostics.clear();
}
+
DelayedDiagnosticPool &operator=(DelayedDiagnosticPool &&Other) {
Parent = Other.Parent;
Diagnostics = std::move(Other.Diagnostics);
@@ -269,6 +288,12 @@ public:
return *this;
}
+ ~DelayedDiagnosticPool() {
+ for (SmallVectorImpl<DelayedDiagnostic>::iterator
+ i = Diagnostics.begin(), e = Diagnostics.end(); i != e; ++i)
+ i->Destroy();
+ }
+
const DelayedDiagnosticPool *getParent() const { return Parent; }
/// Does this pool, or any of its ancestors, contain any diagnostics?
@@ -293,13 +318,14 @@ public:
pool.Diagnostics.clear();
}
- typedef SmallVectorImpl<DelayedDiagnostic>::const_iterator pool_iterator;
+ using pool_iterator = SmallVectorImpl<DelayedDiagnostic>::const_iterator;
+
pool_iterator pool_begin() const { return Diagnostics.begin(); }
pool_iterator pool_end() const { return Diagnostics.end(); }
bool pool_empty() const { return Diagnostics.empty(); }
};
-}
+} // namespace clang
/// Add a diagnostic to the current delay pool.
inline void Sema::DelayedDiagnostics::add(const sema::DelayedDiagnostic &diag) {
@@ -307,7 +333,6 @@ inline void Sema::DelayedDiagnostics::add(const sema::DelayedDiagnostic &diag) {
CurPool->add(diag);
}
+} // namespace clang
-}
-
-#endif
+#endif // LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h
index c5cb7b12b3f18..42754b33e2df2 100644
--- a/include/clang/Sema/ExternalSemaSource.h
+++ b/include/clang/Sema/ExternalSemaSource.h
@@ -39,7 +39,7 @@ class ValueDecl;
class VarDecl;
struct LateParsedTemplate;
-/// \brief A simple structure that captures a vtable use for the purposes of
+/// A simple structure that captures a vtable use for the purposes of
/// the \c ExternalSemaSource.
struct ExternalVTableUse {
CXXRecordDecl *Record;
@@ -47,7 +47,7 @@ struct ExternalVTableUse {
bool DefinitionRequired;
};
-/// \brief An abstract interface that should be implemented by
+/// An abstract interface that should be implemented by
/// external AST sources that also provide information for semantic
/// analysis.
class ExternalSemaSource : public ExternalASTSource {
@@ -58,15 +58,15 @@ public:
~ExternalSemaSource() override;
- /// \brief Initialize the semantic source with the Sema instance
+ /// Initialize the semantic source with the Sema instance
/// being used to perform semantic analysis on the abstract syntax
/// tree.
virtual void InitializeSema(Sema &S) {}
- /// \brief Inform the semantic consumer that Sema is no longer available.
+ /// Inform the semantic consumer that Sema is no longer available.
virtual void ForgetSema() {}
- /// \brief Load the contents of the global method pool for a given
+ /// Load the contents of the global method pool for a given
/// selector.
virtual void ReadMethodPool(Selector Sel);
@@ -74,12 +74,12 @@ public:
/// selector if necessary.
virtual void updateOutOfDateSelector(Selector Sel);
- /// \brief Load the set of namespaces that are known to the external source,
+ /// Load the set of namespaces that are known to the external source,
/// which will be used during typo correction.
virtual void ReadKnownNamespaces(
SmallVectorImpl<NamespaceDecl *> &Namespaces);
- /// \brief Load the set of used but not defined functions or variables with
+ /// Load the set of used but not defined functions or variables with
/// internal linkage, or used but not defined internal functions.
virtual void
ReadUndefinedButUsed(llvm::MapVector<NamedDecl *, SourceLocation> &Undefined);
@@ -87,7 +87,7 @@ public:
virtual void ReadMismatchingDeleteExpressions(llvm::MapVector<
FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &);
- /// \brief Do last resort, unqualified lookup on a LookupResult that
+ /// Do last resort, unqualified lookup on a LookupResult that
/// Sema cannot find.
///
/// \param R a LookupResult that is being recovered.
@@ -97,7 +97,7 @@ public:
/// \return true to tell Sema to recover using the LookupResult.
virtual bool LookupUnqualified(LookupResult &R, Scope *S) { return false; }
- /// \brief Read the set of tentative definitions known to the external Sema
+ /// Read the set of tentative definitions known to the external Sema
/// source.
///
/// The external source should append its own tentative definitions to the
@@ -107,7 +107,7 @@ public:
virtual void ReadTentativeDefinitions(
SmallVectorImpl<VarDecl *> &TentativeDefs) {}
- /// \brief Read the set of unused file-scope declarations known to the
+ /// Read the set of unused file-scope declarations known to the
/// external Sema source.
///
/// The external source should append its own unused, filed-scope to the
@@ -117,7 +117,7 @@ public:
virtual void ReadUnusedFileScopedDecls(
SmallVectorImpl<const DeclaratorDecl *> &Decls) {}
- /// \brief Read the set of delegating constructors known to the
+ /// Read the set of delegating constructors known to the
/// external Sema source.
///
/// The external source should append its own delegating constructors to the
@@ -127,7 +127,7 @@ public:
virtual void ReadDelegatingConstructors(
SmallVectorImpl<CXXConstructorDecl *> &Decls) {}
- /// \brief Read the set of ext_vector type declarations known to the
+ /// Read the set of ext_vector type declarations known to the
/// external Sema source.
///
/// The external source should append its own ext_vector type declarations to
@@ -136,7 +136,7 @@ public:
/// introduce the same declarations repeatedly.
virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {}
- /// \brief Read the set of potentially unused typedefs known to the source.
+ /// Read the set of potentially unused typedefs known to the source.
///
/// The external source should append its own potentially unused local
/// typedefs to the given vector of declarations. Note that this routine may
@@ -145,7 +145,7 @@ public:
virtual void ReadUnusedLocalTypedefNameCandidates(
llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {}
- /// \brief Read the set of referenced selectors known to the
+ /// Read the set of referenced selectors known to the
/// external Sema source.
///
/// The external source should append its own referenced selectors to the
@@ -155,7 +155,7 @@ public:
virtual void ReadReferencedSelectors(
SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {}
- /// \brief Read the set of weak, undeclared identifiers known to the
+ /// Read the set of weak, undeclared identifiers known to the
/// external Sema source.
///
/// The external source should append its own weak, undeclared identifiers to
@@ -165,14 +165,14 @@ public:
virtual void ReadWeakUndeclaredIdentifiers(
SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) {}
- /// \brief Read the set of used vtables known to the external Sema source.
+ /// Read the set of used vtables known to the external Sema source.
///
/// The external source should append its own used vtables to the given
/// vector. Note that this routine may be invoked multiple times; the external
/// source should take care not to introduce the same vtables repeatedly.
virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {}
- /// \brief Read the set of pending instantiations known to the external
+ /// Read the set of pending instantiations known to the external
/// Sema source.
///
/// The external source should append its own pending instantiations to the
@@ -183,7 +183,7 @@ public:
SmallVectorImpl<std::pair<ValueDecl *,
SourceLocation> > &Pending) {}
- /// \brief Read the set of late parsed template functions for this source.
+ /// Read the set of late parsed template functions for this source.
///
/// The external source should insert its own late parsed template functions
/// into the map. Note that this routine may be invoked multiple times; the
@@ -209,7 +209,7 @@ public:
return TypoCorrection();
}
- /// \brief Produces a diagnostic note if the external source contains a
+ /// Produces a diagnostic note if the external source contains a
/// complete definition for \p T.
///
/// \param Loc the location at which a complete type was required but not
diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h
index 382fe80bea7da..ea6c3df74af0b 100644
--- a/include/clang/Sema/IdentifierResolver.h
+++ b/include/clang/Sema/IdentifierResolver.h
@@ -15,16 +15,20 @@
#ifndef LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
#define LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
-#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
namespace clang {
-class ASTContext;
class Decl;
-class DeclContext;
class DeclarationName;
-class ExternalPreprocessorSource;
+class DeclContext;
+class IdentifierInfo;
+class LangOptions;
class NamedDecl;
class Preprocessor;
class Scope;
@@ -33,17 +37,16 @@ class Scope;
/// scopes. It manages the shadowing chains of declaration names and
/// implements efficient decl lookup based on a declaration name.
class IdentifierResolver {
-
/// IdDeclInfo - Keeps track of information about decls associated
/// to a particular declaration name. IdDeclInfos are lazily
/// constructed and assigned to a declaration name the first time a
/// decl with that declaration name is shadowed in some scope.
class IdDeclInfo {
public:
- typedef SmallVector<NamedDecl*, 2> DeclsTy;
+ using DeclsTy = SmallVector<NamedDecl *, 2>;
- inline DeclsTy::iterator decls_begin() { return Decls.begin(); }
- inline DeclsTy::iterator decls_end() { return Decls.end(); }
+ DeclsTy::iterator decls_begin() { return Decls.begin(); }
+ DeclsTy::iterator decls_end() { return Decls.end(); }
void AddDecl(NamedDecl *D) { Decls.push_back(D); }
@@ -51,7 +54,7 @@ class IdentifierResolver {
/// The decl must already be part of the decl chain.
void RemoveDecl(NamedDecl *D);
- /// \brief Insert the given declaration at the given position in the list.
+ /// Insert the given declaration at the given position in the list.
void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) {
Decls.insert(Pos, D);
}
@@ -61,30 +64,32 @@ class IdentifierResolver {
};
public:
-
/// iterator - Iterate over the decls of a specified declaration name.
/// It will walk or not the parent declaration contexts depending on how
/// it was instantiated.
class iterator {
public:
- typedef NamedDecl * value_type;
- typedef NamedDecl * reference;
- typedef NamedDecl * pointer;
- typedef std::input_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
+ friend class IdentifierResolver;
+
+ using value_type = NamedDecl *;
+ using reference = NamedDecl *;
+ using pointer = NamedDecl *;
+ using iterator_category = std::input_iterator_tag;
+ using difference_type = std::ptrdiff_t;
/// Ptr - There are 2 forms that 'Ptr' represents:
/// 1) A single NamedDecl. (Ptr & 0x1 == 0)
/// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
/// same declaration context. (Ptr & 0x1 == 0x1)
- uintptr_t Ptr;
- typedef IdDeclInfo::DeclsTy::iterator BaseIter;
+ uintptr_t Ptr = 0;
+ using BaseIter = IdDeclInfo::DeclsTy::iterator;
/// A single NamedDecl. (Ptr & 0x1 == 0)
iterator(NamedDecl *D) {
Ptr = reinterpret_cast<uintptr_t>(D);
assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
}
+
/// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
/// contexts depending on 'LookInParentCtx'.
iterator(BaseIter I) {
@@ -98,11 +103,10 @@ public:
return reinterpret_cast<BaseIter>(Ptr & ~0x1);
}
- friend class IdentifierResolver;
-
void incrementSlowCase();
+
public:
- iterator() : Ptr(0) {}
+ iterator() = default;
NamedDecl *operator*() const {
if (isIterator())
@@ -128,6 +132,9 @@ public:
}
};
+ explicit IdentifierResolver(Preprocessor &PP);
+ ~IdentifierResolver();
+
/// begin - Returns an iterator for decls with the name 'Name'.
iterator begin(DeclarationName Name);
@@ -156,11 +163,11 @@ public:
/// The decl must already be part of the decl chain.
void RemoveDecl(NamedDecl *D);
- /// \brief Insert the given declaration after the given iterator
+ /// Insert the given declaration after the given iterator
/// position.
void InsertDeclAfter(iterator Pos, NamedDecl *D);
- /// \brief Try to add the given declaration to the top level scope, if it
+ /// Try to add the given declaration to the top level scope, if it
/// (or a redeclaration of it) hasn't already been added.
///
/// \param D The externally-produced declaration to add.
@@ -170,9 +177,6 @@ public:
/// \returns true if the declaration was added, false otherwise.
bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name);
- explicit IdentifierResolver(Preprocessor &PP);
- ~IdentifierResolver();
-
private:
const LangOptions &LangOpt;
Preprocessor &PP;
@@ -193,11 +197,10 @@ private:
assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
&& "Ptr not a IdDeclInfo* !");
return reinterpret_cast<IdDeclInfo*>(
- reinterpret_cast<uintptr_t>(Ptr) & ~0x1
- );
+ reinterpret_cast<uintptr_t>(Ptr) & ~0x1);
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index bd07b9ea9aeeb..7a510f391bda4 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -1,4 +1,4 @@
-//===--- Initialization.h - Semantic Analysis for Initializers --*- C++ -*-===//
+//===- Initialization.h - Semantic Analysis for Initializers ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,85 +10,115 @@
// This file provides supporting data types for initialization of objects.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_SEMA_INITIALIZATION_H
#define LLVM_CLANG_SEMA_INITIALIZATION_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
-#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Overload.h"
#include "clang/Sema/Ownership.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
#include <cassert>
+#include <cstdint>
+#include <string>
namespace clang {
-
+
+class APValue;
class CXXBaseSpecifier;
-class DeclaratorDecl;
-class DeclaratorInfo;
-class FieldDecl;
-class FunctionDecl;
-class ParmVarDecl;
-class Sema;
-class TypeLoc;
-class VarDecl;
+class CXXConstructorDecl;
class ObjCMethodDecl;
-
-/// \brief Describes an entity that is being initialized.
-class InitializedEntity {
+class Sema;
+
+/// Describes an entity that is being initialized.
+class alignas(8) InitializedEntity {
public:
- /// \brief Specifies the kind of entity being initialized.
+ /// Specifies the kind of entity being initialized.
enum EntityKind {
- /// \brief The entity being initialized is a variable.
+ /// The entity being initialized is a variable.
EK_Variable,
- /// \brief The entity being initialized is a function parameter.
+
+ /// The entity being initialized is a function parameter.
EK_Parameter,
- /// \brief The entity being initialized is the result of a function call.
+
+ /// The entity being initialized is the result of a function call.
EK_Result,
- /// \brief The entity being initialized is an exception object that
+
+ /// The entity being initialized is the result of a statement expression.
+ EK_StmtExprResult,
+
+ /// The entity being initialized is an exception object that
/// is being thrown.
EK_Exception,
- /// \brief The entity being initialized is a non-static data member
+
+ /// The entity being initialized is a non-static data member
/// subobject.
EK_Member,
- /// \brief The entity being initialized is an element of an array.
+
+ /// The entity being initialized is an element of an array.
EK_ArrayElement,
- /// \brief The entity being initialized is an object (or array of
+
+ /// The entity being initialized is an object (or array of
/// objects) allocated via new.
EK_New,
- /// \brief The entity being initialized is a temporary object.
+
+ /// The entity being initialized is a temporary object.
EK_Temporary,
- /// \brief The entity being initialized is a base member subobject.
+
+ /// The entity being initialized is a base member subobject.
EK_Base,
- /// \brief The initialization is being done by a delegating constructor.
+
+ /// The initialization is being done by a delegating constructor.
EK_Delegating,
- /// \brief The entity being initialized is an element of a vector.
+
+ /// The entity being initialized is an element of a vector.
/// or vector.
EK_VectorElement,
- /// \brief The entity being initialized is a field of block descriptor for
+
+ /// The entity being initialized is a field of block descriptor for
/// the copied-in c++ object.
EK_BlockElement,
+
/// The entity being initialized is a field of block descriptor for the
/// copied-in lambda object that's used in the lambda to block conversion.
EK_LambdaToBlockConversionBlockElement,
- /// \brief The entity being initialized is the real or imaginary part of a
+
+ /// The entity being initialized is the real or imaginary part of a
/// complex number.
EK_ComplexElement,
- /// \brief The entity being initialized is the field that captures a
+
+ /// The entity being initialized is the field that captures a
/// variable in a lambda.
EK_LambdaCapture,
- /// \brief The entity being initialized is the initializer for a compound
+
+ /// The entity being initialized is the initializer for a compound
/// literal.
EK_CompoundLiteralInit,
- /// \brief The entity being implicitly initialized back to the formal
+
+ /// The entity being implicitly initialized back to the formal
/// result type.
EK_RelatedResult,
- /// \brief The entity being initialized is a function parameter; function
+
+ /// The entity being initialized is a function parameter; function
/// is member of group of audited CF APIs.
EK_Parameter_CF_Audited,
- /// \brief The entity being initialized is a structured binding of a
+
+ /// The entity being initialized is a structured binding of a
/// decomposition declaration.
EK_Binding,
@@ -96,75 +126,79 @@ public:
// enum as an index for its first %select. When modifying this list,
// that diagnostic text needs to be updated as well.
};
-
+
private:
- /// \brief The kind of entity being initialized.
+ /// The kind of entity being initialized.
EntityKind Kind;
- /// \brief If non-NULL, the parent entity in which this
+ /// If non-NULL, the parent entity in which this
/// initialization occurs.
- const InitializedEntity *Parent;
+ const InitializedEntity *Parent = nullptr;
- /// \brief The type of the object or reference being initialized.
+ /// The type of the object or reference being initialized.
QualType Type;
- /// \brief The mangling number for the next reference temporary to be created.
- mutable unsigned ManglingNumber;
+ /// The mangling number for the next reference temporary to be created.
+ mutable unsigned ManglingNumber = 0;
struct LN {
- /// \brief When Kind == EK_Result, EK_Exception, EK_New, the
+ /// When Kind == EK_Result, EK_Exception, EK_New, the
/// location of the 'return', 'throw', or 'new' keyword,
/// respectively. When Kind == EK_Temporary, the location where
/// the temporary is being created.
unsigned Location;
- /// \brief Whether the entity being initialized may end up using the
+ /// Whether the entity being initialized may end up using the
/// named return value optimization (NRVO).
bool NRVO;
};
struct VD {
- /// \brief The VarDecl, FieldDecl, or BindingDecl being initialized.
+ /// The VarDecl, FieldDecl, or BindingDecl being initialized.
ValueDecl *VariableOrMember;
- /// \brief When Kind == EK_Member, whether this is an implicit member
+ /// When Kind == EK_Member, whether this is an implicit member
/// initialization in a copy or move constructor. These can perform array
/// copies.
bool IsImplicitFieldInit;
+
+ /// When Kind == EK_Member, whether this is the initial initialization
+ /// check for a default member initializer.
+ bool IsDefaultMemberInit;
};
struct C {
- /// \brief The name of the variable being captured by an EK_LambdaCapture.
+ /// The name of the variable being captured by an EK_LambdaCapture.
IdentifierInfo *VarID;
- /// \brief The source location at which the capture occurs.
+ /// The source location at which the capture occurs.
unsigned Location;
};
union {
- /// \brief When Kind == EK_Variable, EK_Member or EK_Binding, the variable.
+ /// When Kind == EK_Variable, EK_Member or EK_Binding, the variable.
VD Variable;
- /// \brief When Kind == EK_RelatedResult, the ObjectiveC method where
+ /// When Kind == EK_RelatedResult, the ObjectiveC method where
/// result type was implicitly changed to accommodate ARC semantics.
ObjCMethodDecl *MethodDecl;
- /// \brief When Kind == EK_Parameter, the ParmVarDecl, with the
+ /// When Kind == EK_Parameter, the ParmVarDecl, with the
/// low bit indicating whether the parameter is "consumed".
uintptr_t Parameter;
- /// \brief When Kind == EK_Temporary or EK_CompoundLiteralInit, the type
+ /// When Kind == EK_Temporary or EK_CompoundLiteralInit, the type
/// source information for the temporary.
TypeSourceInfo *TypeInfo;
struct LN LocAndNRVO;
- /// \brief When Kind == EK_Base, the base specifier that provides the
+ /// When Kind == EK_Base, the base specifier that provides the
/// base class. The lower bit specifies whether the base is an inherited
/// virtual base.
uintptr_t Base;
- /// \brief When Kind == EK_ArrayElement, EK_VectorElement, or
+ /// When Kind == EK_ArrayElement, EK_VectorElement, or
/// EK_ComplexElement, the index of the array or vector element being
/// initialized.
unsigned Index;
@@ -172,57 +206,52 @@ private:
struct C Capture;
};
- InitializedEntity() : ManglingNumber(0) {}
+ InitializedEntity() = default;
- /// \brief Create the initialization entity for a variable.
+ /// Create the initialization entity for a variable.
InitializedEntity(VarDecl *Var, EntityKind EK = EK_Variable)
- : Kind(EK), Parent(nullptr), Type(Var->getType()),
- ManglingNumber(0), Variable{Var, false} { }
+ : Kind(EK), Type(Var->getType()), Variable{Var, false, false} {}
- /// \brief Create the initialization entity for the result of a
+ /// Create the initialization entity for the result of a
/// function, throwing an object, performing an explicit cast, or
/// initializing a parameter for which there is no declaration.
InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
bool NRVO = false)
- : Kind(Kind), Parent(nullptr), Type(Type), ManglingNumber(0)
- {
+ : Kind(Kind), Type(Type) {
LocAndNRVO.Location = Loc.getRawEncoding();
LocAndNRVO.NRVO = NRVO;
}
- /// \brief Create the initialization entity for a member subobject.
+ /// Create the initialization entity for a member subobject.
InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent,
- bool Implicit)
- : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
- ManglingNumber(0), Variable{Member, Implicit} {
- }
+ bool Implicit, bool DefaultMemberInit)
+ : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
+ Variable{Member, Implicit, DefaultMemberInit} {}
- /// \brief Create the initialization entity for an array element.
+ /// Create the initialization entity for an array element.
InitializedEntity(ASTContext &Context, unsigned Index,
const InitializedEntity &Parent);
- /// \brief Create the initialization entity for a lambda capture.
+ /// Create the initialization entity for a lambda capture.
InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc)
- : Kind(EK_LambdaCapture), Parent(nullptr), Type(FieldType),
- ManglingNumber(0)
- {
+ : Kind(EK_LambdaCapture), Type(FieldType) {
Capture.VarID = VarID;
Capture.Location = Loc.getRawEncoding();
}
public:
- /// \brief Create the initialization entity for a variable.
+ /// Create the initialization entity for a variable.
static InitializedEntity InitializeVariable(VarDecl *Var) {
return InitializedEntity(Var);
}
- /// \brief Create the initialization entity for a parameter.
+ /// Create the initialization entity for a parameter.
static InitializedEntity InitializeParameter(ASTContext &Context,
const ParmVarDecl *Parm) {
return InitializeParameter(Context, Parm, Parm->getType());
}
- /// \brief Create the initialization entity for a parameter, but use
+ /// Create the initialization entity for a parameter, but use
/// another type.
static InitializedEntity InitializeParameter(ASTContext &Context,
const ParmVarDecl *Parm,
@@ -240,7 +269,7 @@ public:
return Entity;
}
- /// \brief Create the initialization entity for a parameter that is
+ /// Create the initialization entity for a parameter that is
/// only known by its type.
static InitializedEntity InitializeParameter(ASTContext &Context,
QualType Type,
@@ -253,12 +282,17 @@ public:
return Entity;
}
- /// \brief Create the initialization entity for the result of a function.
+ /// Create the initialization entity for the result of a function.
static InitializedEntity InitializeResult(SourceLocation ReturnLoc,
QualType Type, bool NRVO) {
return InitializedEntity(EK_Result, ReturnLoc, Type, NRVO);
}
+ static InitializedEntity InitializeStmtExprResult(SourceLocation ReturnLoc,
+ QualType Type) {
+ return InitializedEntity(EK_StmtExprResult, ReturnLoc, Type);
+ }
+
static InitializedEntity InitializeBlock(SourceLocation BlockVarLoc,
QualType Type, bool NRVO) {
return InitializedEntity(EK_BlockElement, BlockVarLoc, Type, NRVO);
@@ -270,28 +304,28 @@ public:
BlockVarLoc, Type, NRVO);
}
- /// \brief Create the initialization entity for an exception object.
+ /// Create the initialization entity for an exception object.
static InitializedEntity InitializeException(SourceLocation ThrowLoc,
QualType Type, bool NRVO) {
return InitializedEntity(EK_Exception, ThrowLoc, Type, NRVO);
}
- /// \brief Create the initialization entity for an object allocated via new.
+ /// Create the initialization entity for an object allocated via new.
static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type) {
return InitializedEntity(EK_New, NewLoc, Type);
}
- /// \brief Create the initialization entity for a temporary.
+ /// Create the initialization entity for a temporary.
static InitializedEntity InitializeTemporary(QualType Type) {
return InitializeTemporary(nullptr, Type);
}
- /// \brief Create the initialization entity for a temporary.
+ /// Create the initialization entity for a temporary.
static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo) {
return InitializeTemporary(TypeInfo, TypeInfo->getType());
}
- /// \brief Create the initialization entity for a temporary.
+ /// Create the initialization entity for a temporary.
static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo,
QualType Type) {
InitializedEntity Result(EK_Temporary, SourceLocation(), Type);
@@ -299,7 +333,7 @@ public:
return Result;
}
- /// \brief Create the initialization entity for a related result.
+ /// Create the initialization entity for a related result.
static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD,
QualType Type) {
InitializedEntity Result(EK_RelatedResult, SourceLocation(), Type);
@@ -307,54 +341,59 @@ public:
return Result;
}
-
- /// \brief Create the initialization entity for a base class subobject.
+ /// Create the initialization entity for a base class subobject.
static InitializedEntity
InitializeBase(ASTContext &Context, const CXXBaseSpecifier *Base,
bool IsInheritedVirtualBase,
const InitializedEntity *Parent = nullptr);
- /// \brief Create the initialization entity for a delegated constructor.
+ /// Create the initialization entity for a delegated constructor.
static InitializedEntity InitializeDelegation(QualType Type) {
return InitializedEntity(EK_Delegating, SourceLocation(), Type);
}
-
- /// \brief Create the initialization entity for a member subobject.
+
+ /// Create the initialization entity for a member subobject.
static InitializedEntity
InitializeMember(FieldDecl *Member,
const InitializedEntity *Parent = nullptr,
bool Implicit = false) {
- return InitializedEntity(Member, Parent, Implicit);
+ return InitializedEntity(Member, Parent, Implicit, false);
}
-
- /// \brief Create the initialization entity for a member subobject.
+
+ /// Create the initialization entity for a member subobject.
static InitializedEntity
InitializeMember(IndirectFieldDecl *Member,
const InitializedEntity *Parent = nullptr,
bool Implicit = false) {
- return InitializedEntity(Member->getAnonField(), Parent, Implicit);
+ return InitializedEntity(Member->getAnonField(), Parent, Implicit, false);
}
- /// \brief Create the initialization entity for an array element.
+ /// Create the initialization entity for a default member initializer.
+ static InitializedEntity
+ InitializeMemberFromDefaultMemberInitializer(FieldDecl *Member) {
+ return InitializedEntity(Member, nullptr, false, true);
+ }
+
+ /// Create the initialization entity for an array element.
static InitializedEntity InitializeElement(ASTContext &Context,
unsigned Index,
const InitializedEntity &Parent) {
return InitializedEntity(Context, Index, Parent);
}
- /// \brief Create the initialization entity for a structured binding.
+ /// Create the initialization entity for a structured binding.
static InitializedEntity InitializeBinding(VarDecl *Binding) {
return InitializedEntity(Binding, EK_Binding);
}
- /// \brief Create the initialization entity for a lambda capture.
+ /// Create the initialization entity for a lambda capture.
static InitializedEntity InitializeLambdaCapture(IdentifierInfo *VarID,
QualType FieldType,
SourceLocation Loc) {
return InitializedEntity(VarID, FieldType, Loc);
}
- /// \brief Create the entity for a compound literal initializer.
+ /// Create the entity for a compound literal initializer.
static InitializedEntity InitializeCompoundLiteralInit(TypeSourceInfo *TSI) {
InitializedEntity Result(EK_CompoundLiteralInit, SourceLocation(),
TSI->getType());
@@ -362,19 +401,18 @@ public:
return Result;
}
-
- /// \brief Determine the kind of initialization.
+ /// Determine the kind of initialization.
EntityKind getKind() const { return Kind; }
- /// \brief Retrieve the parent of the entity being initialized, when
+ /// Retrieve the parent of the entity being initialized, when
/// the initialization itself is occurring within the context of a
/// larger initialization.
const InitializedEntity *getParent() const { return Parent; }
- /// \brief Retrieve type being initialized.
+ /// Retrieve type being initialized.
QualType getType() const { return Type; }
- /// \brief Retrieve complete type-source information for the object being
+ /// Retrieve complete type-source information for the object being
/// constructed, if known.
TypeSourceInfo *getTypeSourceInfo() const {
if (Kind == EK_Temporary || Kind == EK_CompoundLiteralInit)
@@ -383,17 +421,17 @@ public:
return nullptr;
}
- /// \brief Retrieve the name of the entity being initialized.
+ /// Retrieve the name of the entity being initialized.
DeclarationName getName() const;
- /// \brief Retrieve the variable, parameter, or field being
+ /// Retrieve the variable, parameter, or field being
/// initialized.
ValueDecl *getDecl() const;
- /// \brief Retrieve the ObjectiveC method being initialized.
+ /// Retrieve the ObjectiveC method being initialized.
ObjCMethodDecl *getMethodDecl() const { return MethodDecl; }
- /// \brief Determine whether this initialization allows the named return
+ /// Determine whether this initialization allows the named return
/// value optimization, which also applies to thrown objects.
bool allowsNRVO() const;
@@ -401,71 +439,81 @@ public:
return (getKind() == EK_Parameter ||
getKind() == EK_Parameter_CF_Audited);
}
- /// \brief Determine whether this initialization consumes the
+
+ /// Determine whether this initialization consumes the
/// parameter.
bool isParameterConsumed() const {
assert(isParameterKind() && "Not a parameter");
return (Parameter & 1);
}
- /// \brief Retrieve the base specifier.
+ /// Retrieve the base specifier.
const CXXBaseSpecifier *getBaseSpecifier() const {
assert(getKind() == EK_Base && "Not a base specifier");
return reinterpret_cast<const CXXBaseSpecifier *>(Base & ~0x1);
}
- /// \brief Return whether the base is an inherited virtual base.
+ /// Return whether the base is an inherited virtual base.
bool isInheritedVirtualBase() const {
assert(getKind() == EK_Base && "Not a base specifier");
return Base & 0x1;
}
- /// \brief Determine whether this is an array new with an unknown bound.
+ /// Determine whether this is an array new with an unknown bound.
bool isVariableLengthArrayNew() const {
return getKind() == EK_New && dyn_cast_or_null<IncompleteArrayType>(
getType()->getAsArrayTypeUnsafe());
}
- /// \brief Is this the implicit initialization of a member of a class from
+ /// Is this the implicit initialization of a member of a class from
/// a defaulted constructor?
bool isImplicitMemberInitializer() const {
return getKind() == EK_Member && Variable.IsImplicitFieldInit;
}
- /// \brief Determine the location of the 'return' keyword when initializing
+ /// Is this the default member initializer of a member (specified inside
+ /// the class definition)?
+ bool isDefaultMemberInitializer() const {
+ return getKind() == EK_Member && Variable.IsDefaultMemberInit;
+ }
+
+ /// Determine the location of the 'return' keyword when initializing
/// the result of a function call.
SourceLocation getReturnLoc() const {
assert(getKind() == EK_Result && "No 'return' location!");
return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);
}
- /// \brief Determine the location of the 'throw' keyword when initializing
+ /// Determine the location of the 'throw' keyword when initializing
/// an exception object.
SourceLocation getThrowLoc() const {
assert(getKind() == EK_Exception && "No 'throw' location!");
return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);
}
- /// \brief If this is an array, vector, or complex number element, get the
+ /// If this is an array, vector, or complex number element, get the
/// element's index.
unsigned getElementIndex() const {
assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||
getKind() == EK_ComplexElement);
return Index;
}
- /// \brief If this is already the initializer for an array or vector
+
+ /// If this is already the initializer for an array or vector
/// element, sets the element index.
void setElementIndex(unsigned Index) {
assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||
getKind() == EK_ComplexElement);
this->Index = Index;
}
- /// \brief For a lambda capture, return the capture's name.
+
+ /// For a lambda capture, return the capture's name.
StringRef getCapturedVarName() const {
assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
return Capture.VarID->getName();
}
- /// \brief Determine the location of the capture when initializing
+
+ /// Determine the location of the capture when initializing
/// field from a captured variable in a lambda.
SourceLocation getCaptureLoc() const {
assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
@@ -486,51 +534,70 @@ private:
unsigned dumpImpl(raw_ostream &OS) const;
};
-/// \brief Describes the kind of initialization being performed, along with
+/// Describes the kind of initialization being performed, along with
/// location information for tokens related to the initialization (equal sign,
/// parentheses).
class InitializationKind {
public:
- /// \brief The kind of initialization being performed.
+ /// The kind of initialization being performed.
enum InitKind {
- IK_Direct, ///< Direct initialization
- IK_DirectList, ///< Direct list-initialization
- IK_Copy, ///< Copy initialization
- IK_Default, ///< Default initialization
- IK_Value ///< Value initialization
+ /// Direct initialization
+ IK_Direct,
+
+ /// Direct list-initialization
+ IK_DirectList,
+
+ /// Copy initialization
+ IK_Copy,
+
+ /// Default initialization
+ IK_Default,
+
+ /// Value initialization
+ IK_Value
};
private:
- /// \brief The context of the initialization.
+ /// The context of the initialization.
enum InitContext {
- IC_Normal, ///< Normal context
- IC_ExplicitConvs, ///< Normal context, but allows explicit conversion funcs
- IC_Implicit, ///< Implicit context (value initialization)
- IC_StaticCast, ///< Static cast context
- IC_CStyleCast, ///< C-style cast context
- IC_FunctionalCast ///< Functional cast context
+ /// Normal context
+ IC_Normal,
+
+ /// Normal context, but allows explicit conversion functionss
+ IC_ExplicitConvs,
+
+ /// Implicit context (value initialization)
+ IC_Implicit,
+
+ /// Static cast context
+ IC_StaticCast,
+
+ /// C-style cast context
+ IC_CStyleCast,
+
+ /// Functional cast context
+ IC_FunctionalCast
};
- /// \brief The kind of initialization being performed.
+ /// The kind of initialization being performed.
InitKind Kind : 8;
- /// \brief The context of the initialization.
+ /// The context of the initialization.
InitContext Context : 8;
- /// \brief The source locations involved in the initialization.
+ /// The source locations involved in the initialization.
SourceLocation Locations[3];
InitializationKind(InitKind Kind, InitContext Context, SourceLocation Loc1,
SourceLocation Loc2, SourceLocation Loc3)
- : Kind(Kind), Context(Context)
- {
+ : Kind(Kind), Context(Context) {
Locations[0] = Loc1;
Locations[1] = Loc2;
Locations[2] = Loc3;
}
public:
- /// \brief Create a direct initialization.
+ /// Create a direct initialization.
static InitializationKind CreateDirect(SourceLocation InitLoc,
SourceLocation LParenLoc,
SourceLocation RParenLoc) {
@@ -539,18 +606,25 @@ public:
}
static InitializationKind CreateDirectList(SourceLocation InitLoc) {
- return InitializationKind(IK_DirectList, IC_Normal,
- InitLoc, InitLoc, InitLoc);
+ return InitializationKind(IK_DirectList, IC_Normal, InitLoc, InitLoc,
+ InitLoc);
}
- /// \brief Create a direct initialization due to a cast that isn't a C-style
+ static InitializationKind CreateDirectList(SourceLocation InitLoc,
+ SourceLocation LBraceLoc,
+ SourceLocation RBraceLoc) {
+ return InitializationKind(IK_DirectList, IC_Normal, InitLoc, LBraceLoc,
+ RBraceLoc);
+ }
+
+ /// Create a direct initialization due to a cast that isn't a C-style
/// or functional cast.
static InitializationKind CreateCast(SourceRange TypeRange) {
return InitializationKind(IK_Direct, IC_StaticCast, TypeRange.getBegin(),
TypeRange.getBegin(), TypeRange.getEnd());
}
- /// \brief Create a direct initialization for a C-style cast.
+ /// Create a direct initialization for a C-style cast.
static InitializationKind CreateCStyleCast(SourceLocation StartLoc,
SourceRange TypeRange,
bool InitList) {
@@ -561,7 +635,7 @@ public:
TypeRange.getEnd());
}
- /// \brief Create a direct initialization for a functional cast.
+ /// Create a direct initialization for a functional cast.
static InitializationKind CreateFunctionalCast(SourceRange TypeRange,
bool InitList) {
return InitializationKind(InitList ? IK_DirectList : IK_Direct,
@@ -569,7 +643,7 @@ public:
TypeRange.getBegin(), TypeRange.getEnd());
}
- /// \brief Create a copy initialization.
+ /// Create a copy initialization.
static InitializationKind CreateCopy(SourceLocation InitLoc,
SourceLocation EqualLoc,
bool AllowExplicitConvs = false) {
@@ -578,12 +652,12 @@ public:
InitLoc, EqualLoc, EqualLoc);
}
- /// \brief Create a default initialization.
+ /// Create a default initialization.
static InitializationKind CreateDefault(SourceLocation InitLoc) {
return InitializationKind(IK_Default, IC_Normal, InitLoc, InitLoc, InitLoc);
}
- /// \brief Create a value initialization.
+ /// Create a value initialization.
static InitializationKind CreateValue(SourceLocation InitLoc,
SourceLocation LParenLoc,
SourceLocation RParenLoc,
@@ -592,55 +666,56 @@ public:
InitLoc, LParenLoc, RParenLoc);
}
- /// \brief Create an initialization from an initializer (which, for direct
+ /// Create an initialization from an initializer (which, for direct
/// initialization from a parenthesized list, will be a ParenListExpr).
static InitializationKind CreateForInit(SourceLocation Loc, bool DirectInit,
Expr *Init) {
if (!Init) return CreateDefault(Loc);
if (!DirectInit) return CreateCopy(Loc, Init->getLocStart());
- if (isa<InitListExpr>(Init)) return CreateDirectList(Loc);
+ if (isa<InitListExpr>(Init))
+ return CreateDirectList(Loc, Init->getLocStart(), Init->getLocEnd());
return CreateDirect(Loc, Init->getLocStart(), Init->getLocEnd());
}
- /// \brief Determine the initialization kind.
+ /// Determine the initialization kind.
InitKind getKind() const {
return Kind;
}
- /// \brief Determine whether this initialization is an explicit cast.
+ /// Determine whether this initialization is an explicit cast.
bool isExplicitCast() const {
return Context >= IC_StaticCast;
}
- /// \brief Determine whether this initialization is a C-style cast.
+ /// Determine whether this initialization is a C-style cast.
bool isCStyleOrFunctionalCast() const {
return Context >= IC_CStyleCast;
}
- /// \brief Determine whether this is a C-style cast.
+ /// Determine whether this is a C-style cast.
bool isCStyleCast() const {
return Context == IC_CStyleCast;
}
- /// \brief Determine whether this is a functional-style cast.
+ /// Determine whether this is a functional-style cast.
bool isFunctionalCast() const {
return Context == IC_FunctionalCast;
}
- /// \brief Determine whether this initialization is an implicit
+ /// Determine whether this initialization is an implicit
/// value-initialization, e.g., as occurs during aggregate
/// initialization.
bool isImplicitValueInit() const { return Context == IC_Implicit; }
- /// \brief Retrieve the location at which initialization is occurring.
+ /// Retrieve the location at which initialization is occurring.
SourceLocation getLocation() const { return Locations[0]; }
- /// \brief Retrieve the source range that covers the initialization.
+ /// Retrieve the source range that covers the initialization.
SourceRange getRange() const {
return SourceRange(Locations[0], Locations[2]);
}
- /// \brief Retrieve the location of the equal sign for copy initialization
+ /// Retrieve the location of the equal sign for copy initialization
/// (if present).
SourceLocation getEqualLoc() const {
assert(Kind == IK_Copy && "Only copy initialization has an '='");
@@ -649,143 +724,188 @@ public:
bool isCopyInit() const { return Kind == IK_Copy; }
- /// \brief Retrieve whether this initialization allows the use of explicit
+ /// Retrieve whether this initialization allows the use of explicit
/// constructors.
bool AllowExplicit() const { return !isCopyInit(); }
- /// \brief Retrieve whether this initialization allows the use of explicit
+ /// Retrieve whether this initialization allows the use of explicit
/// conversion functions when binding a reference. If the reference is the
/// first parameter in a copy or move constructor, such conversions are
/// permitted even though we are performing copy-initialization.
bool allowExplicitConversionFunctionsInRefBinding() const {
return !isCopyInit() || Context == IC_ExplicitConvs;
}
+
+ /// Determine whether this initialization has a source range containing the
+ /// locations of open and closing parentheses or braces.
+ bool hasParenOrBraceRange() const {
+ return Kind == IK_Direct || Kind == IK_Value || Kind == IK_DirectList;
+ }
- /// \brief Retrieve the source range containing the locations of the open
- /// and closing parentheses for value and direct initializations.
- SourceRange getParenRange() const {
- assert((Kind == IK_Direct || Kind == IK_Value) &&
- "Only direct- and value-initialization have parentheses");
+ /// Retrieve the source range containing the locations of the open
+ /// and closing parentheses or braces for value, direct, and direct list
+ /// initializations.
+ SourceRange getParenOrBraceRange() const {
+ assert(hasParenOrBraceRange() && "Only direct, value, and direct-list "
+ "initialization have parentheses or "
+ "braces");
return SourceRange(Locations[1], Locations[2]);
}
};
-/// \brief Describes the sequence of initializations required to initialize
+/// Describes the sequence of initializations required to initialize
/// a given object or reference with a set of arguments.
class InitializationSequence {
public:
- /// \brief Describes the kind of initialization sequence computed.
+ /// Describes the kind of initialization sequence computed.
enum SequenceKind {
- /// \brief A failed initialization sequence. The failure kind tells what
+ /// A failed initialization sequence. The failure kind tells what
/// happened.
FailedSequence = 0,
- /// \brief A dependent initialization, which could not be
+ /// A dependent initialization, which could not be
/// type-checked due to the presence of dependent types or
/// dependently-typed expressions.
DependentSequence,
- /// \brief A normal sequence.
+ /// A normal sequence.
NormalSequence
};
- /// \brief Describes the kind of a particular step in an initialization
+ /// Describes the kind of a particular step in an initialization
/// sequence.
enum StepKind {
- /// \brief Resolve the address of an overloaded function to a specific
+ /// Resolve the address of an overloaded function to a specific
/// function declaration.
SK_ResolveAddressOfOverloadedFunction,
- /// \brief Perform a derived-to-base cast, producing an rvalue.
+
+ /// Perform a derived-to-base cast, producing an rvalue.
SK_CastDerivedToBaseRValue,
- /// \brief Perform a derived-to-base cast, producing an xvalue.
+
+ /// Perform a derived-to-base cast, producing an xvalue.
SK_CastDerivedToBaseXValue,
- /// \brief Perform a derived-to-base cast, producing an lvalue.
+
+ /// Perform a derived-to-base cast, producing an lvalue.
SK_CastDerivedToBaseLValue,
- /// \brief Reference binding to an lvalue.
+
+ /// Reference binding to an lvalue.
SK_BindReference,
- /// \brief Reference binding to a temporary.
+
+ /// Reference binding to a temporary.
SK_BindReferenceToTemporary,
- /// \brief An optional copy of a temporary object to another
+
+ /// An optional copy of a temporary object to another
/// temporary object, which is permitted (but not required) by
/// C++98/03 but not C++0x.
SK_ExtraneousCopyToTemporary,
- /// \brief Direct-initialization from a reference-related object in the
+
+ /// Direct-initialization from a reference-related object in the
/// final stage of class copy-initialization.
SK_FinalCopy,
- /// \brief Perform a user-defined conversion, either via a conversion
+
+ /// Perform a user-defined conversion, either via a conversion
/// function or via a constructor.
SK_UserConversion,
- /// \brief Perform a qualification conversion, producing an rvalue.
+
+ /// Perform a qualification conversion, producing an rvalue.
SK_QualificationConversionRValue,
- /// \brief Perform a qualification conversion, producing an xvalue.
+
+ /// Perform a qualification conversion, producing an xvalue.
SK_QualificationConversionXValue,
- /// \brief Perform a qualification conversion, producing an lvalue.
+
+ /// Perform a qualification conversion, producing an lvalue.
SK_QualificationConversionLValue,
- /// \brief Perform a conversion adding _Atomic to a type.
+
+ /// Perform a conversion adding _Atomic to a type.
SK_AtomicConversion,
- /// \brief Perform a load from a glvalue, producing an rvalue.
+
+ /// Perform a load from a glvalue, producing an rvalue.
SK_LValueToRValue,
- /// \brief Perform an implicit conversion sequence.
+
+ /// Perform an implicit conversion sequence.
SK_ConversionSequence,
- /// \brief Perform an implicit conversion sequence without narrowing.
+
+ /// Perform an implicit conversion sequence without narrowing.
SK_ConversionSequenceNoNarrowing,
- /// \brief Perform list-initialization without a constructor.
+
+ /// Perform list-initialization without a constructor.
SK_ListInitialization,
- /// \brief Unwrap the single-element initializer list for a reference.
+
+ /// Unwrap the single-element initializer list for a reference.
SK_UnwrapInitList,
- /// \brief Rewrap the single-element initializer list for a reference.
+
+ /// Rewrap the single-element initializer list for a reference.
SK_RewrapInitList,
- /// \brief Perform initialization via a constructor.
+
+ /// Perform initialization via a constructor.
SK_ConstructorInitialization,
- /// \brief Perform initialization via a constructor, taking arguments from
+
+ /// Perform initialization via a constructor, taking arguments from
/// a single InitListExpr.
SK_ConstructorInitializationFromList,
- /// \brief Zero-initialize the object
+
+ /// Zero-initialize the object
SK_ZeroInitialization,
- /// \brief C assignment
+
+ /// C assignment
SK_CAssignment,
- /// \brief Initialization by string
+
+ /// Initialization by string
SK_StringInit,
- /// \brief An initialization that "converts" an Objective-C object
+
+ /// An initialization that "converts" an Objective-C object
/// (not a point to an object) to another Objective-C object type.
SK_ObjCObjectConversion,
- /// \brief Array indexing for initialization by elementwise copy.
+
+ /// Array indexing for initialization by elementwise copy.
SK_ArrayLoopIndex,
- /// \brief Array initialization by elementwise copy.
+
+ /// Array initialization by elementwise copy.
SK_ArrayLoopInit,
- /// \brief Array initialization (from an array rvalue).
+
+ /// Array initialization (from an array rvalue).
SK_ArrayInit,
- /// \brief Array initialization (from an array rvalue) as a GNU extension.
+
+ /// Array initialization (from an array rvalue) as a GNU extension.
SK_GNUArrayInit,
- /// \brief Array initialization from a parenthesized initializer list.
+
+ /// Array initialization from a parenthesized initializer list.
/// This is a GNU C++ extension.
SK_ParenthesizedArrayInit,
- /// \brief Pass an object by indirect copy-and-restore.
+
+ /// Pass an object by indirect copy-and-restore.
SK_PassByIndirectCopyRestore,
- /// \brief Pass an object by indirect restore.
+
+ /// Pass an object by indirect restore.
SK_PassByIndirectRestore,
- /// \brief Produce an Objective-C object pointer.
+
+ /// Produce an Objective-C object pointer.
SK_ProduceObjCObject,
- /// \brief Construct a std::initializer_list from an initializer list.
+
+ /// Construct a std::initializer_list from an initializer list.
SK_StdInitializerList,
- /// \brief Perform initialization via a constructor taking a single
+
+ /// Perform initialization via a constructor taking a single
/// std::initializer_list argument.
SK_StdInitializerListConstructorCall,
- /// \brief Initialize an OpenCL sampler from an integer.
+
+ /// Initialize an OpenCL sampler from an integer.
SK_OCLSamplerInit,
- /// \brief Initialize queue_t from 0.
+
+ /// Initialize queue_t from 0.
SK_OCLZeroQueue,
- /// \brief Passing zero to a function where OpenCL event_t is expected.
+
+ /// Passing zero to a function where OpenCL event_t is expected.
SK_OCLZeroEvent
};
- /// \brief A single step in the initialization sequence.
+ /// A single step in the initialization sequence.
class Step {
public:
- /// \brief The kind of conversion or initialization step we are taking.
+ /// The kind of conversion or initialization step we are taking.
StepKind Kind;
- // \brief The type that results from this initialization.
+ // The type that results from this initialization.
QualType Type;
struct F {
@@ -795,7 +915,7 @@ public:
};
union {
- /// \brief When Kind == SK_ResolvedOverloadedFunction or Kind ==
+ /// When Kind == SK_ResolvedOverloadedFunction or Kind ==
/// SK_UserConversion, the function that the expression should be
/// resolved to or the conversion function to call, respectively.
/// When Kind == SK_ConstructorInitialization or SK_ListConstruction,
@@ -807,11 +927,11 @@ public:
/// For construct decls, the naming class is the target type.
struct F Function;
- /// \brief When Kind = SK_ConversionSequence, the implicit conversion
+ /// When Kind = SK_ConversionSequence, the implicit conversion
/// sequence.
ImplicitConversionSequence *ICS;
- /// \brief When Kind = SK_RewrapInitList, the syntactic form of the
+ /// When Kind = SK_RewrapInitList, the syntactic form of the
/// wrapping list.
InitListExpr *WrappingSyntacticList;
};
@@ -820,114 +940,154 @@ public:
};
private:
- /// \brief The kind of initialization sequence computed.
+ /// The kind of initialization sequence computed.
enum SequenceKind SequenceKind;
- /// \brief Steps taken by this initialization.
+ /// Steps taken by this initialization.
SmallVector<Step, 4> Steps;
public:
- /// \brief Describes why initialization failed.
+ /// Describes why initialization failed.
enum FailureKind {
- /// \brief Too many initializers provided for a reference.
+ /// Too many initializers provided for a reference.
FK_TooManyInitsForReference,
- /// \brief Reference initialized from a parenthesized initializer list.
+
+ /// Reference initialized from a parenthesized initializer list.
FK_ParenthesizedListInitForReference,
- /// \brief Array must be initialized with an initializer list.
+
+ /// Array must be initialized with an initializer list.
FK_ArrayNeedsInitList,
- /// \brief Array must be initialized with an initializer list or a
+
+ /// Array must be initialized with an initializer list or a
/// string literal.
FK_ArrayNeedsInitListOrStringLiteral,
- /// \brief Array must be initialized with an initializer list or a
+
+ /// Array must be initialized with an initializer list or a
/// wide string literal.
FK_ArrayNeedsInitListOrWideStringLiteral,
- /// \brief Initializing a wide char array with narrow string literal.
+
+ /// Initializing a wide char array with narrow string literal.
FK_NarrowStringIntoWideCharArray,
- /// \brief Initializing char array with wide string literal.
+
+ /// Initializing char array with wide string literal.
FK_WideStringIntoCharArray,
- /// \brief Initializing wide char array with incompatible wide string
+
+ /// Initializing wide char array with incompatible wide string
/// literal.
FK_IncompatWideStringIntoWideChar,
- /// \brief Array type mismatch.
+
+ /// Initializing char8_t array with plain string literal.
+ FK_PlainStringIntoUTF8Char,
+
+ /// Initializing char array with UTF-8 string literal.
+ FK_UTF8StringIntoPlainChar,
+
+ /// Array type mismatch.
FK_ArrayTypeMismatch,
- /// \brief Non-constant array initializer
+
+ /// Non-constant array initializer
FK_NonConstantArrayInit,
- /// \brief Cannot resolve the address of an overloaded function.
+
+ /// Cannot resolve the address of an overloaded function.
FK_AddressOfOverloadFailed,
- /// \brief Overloading due to reference initialization failed.
+
+ /// Overloading due to reference initialization failed.
FK_ReferenceInitOverloadFailed,
- /// \brief Non-const lvalue reference binding to a temporary.
+
+ /// Non-const lvalue reference binding to a temporary.
FK_NonConstLValueReferenceBindingToTemporary,
- /// \brief Non-const lvalue reference binding to a bit-field.
+
+ /// Non-const lvalue reference binding to a bit-field.
FK_NonConstLValueReferenceBindingToBitfield,
- /// \brief Non-const lvalue reference binding to a vector element.
+
+ /// Non-const lvalue reference binding to a vector element.
FK_NonConstLValueReferenceBindingToVectorElement,
- /// \brief Non-const lvalue reference binding to an lvalue of unrelated
+
+ /// Non-const lvalue reference binding to an lvalue of unrelated
/// type.
FK_NonConstLValueReferenceBindingToUnrelated,
- /// \brief Rvalue reference binding to an lvalue.
+
+ /// Rvalue reference binding to an lvalue.
FK_RValueReferenceBindingToLValue,
- /// \brief Reference binding drops qualifiers.
+
+ /// Reference binding drops qualifiers.
FK_ReferenceInitDropsQualifiers,
- /// \brief Reference binding failed.
+
+ /// Reference binding failed.
FK_ReferenceInitFailed,
- /// \brief Implicit conversion failed.
+
+ /// Implicit conversion failed.
FK_ConversionFailed,
- /// \brief Implicit conversion failed.
+
+ /// Implicit conversion failed.
FK_ConversionFromPropertyFailed,
- /// \brief Too many initializers for scalar
+
+ /// Too many initializers for scalar
FK_TooManyInitsForScalar,
- /// \brief Scalar initialized from a parenthesized initializer list.
+
+ /// Scalar initialized from a parenthesized initializer list.
FK_ParenthesizedListInitForScalar,
- /// \brief Reference initialization from an initializer list
+
+ /// Reference initialization from an initializer list
FK_ReferenceBindingToInitList,
- /// \brief Initialization of some unused destination type with an
+
+ /// Initialization of some unused destination type with an
/// initializer list.
FK_InitListBadDestinationType,
- /// \brief Overloading for a user-defined conversion failed.
+
+ /// Overloading for a user-defined conversion failed.
FK_UserConversionOverloadFailed,
- /// \brief Overloading for initialization by constructor failed.
+
+ /// Overloading for initialization by constructor failed.
FK_ConstructorOverloadFailed,
- /// \brief Overloading for list-initialization by constructor failed.
+
+ /// Overloading for list-initialization by constructor failed.
FK_ListConstructorOverloadFailed,
- /// \brief Default-initialization of a 'const' object.
+
+ /// Default-initialization of a 'const' object.
FK_DefaultInitOfConst,
- /// \brief Initialization of an incomplete type.
+
+ /// Initialization of an incomplete type.
FK_Incomplete,
- /// \brief Variable-length array must not have an initializer.
+
+ /// Variable-length array must not have an initializer.
FK_VariableLengthArrayHasInitializer,
- /// \brief List initialization failed at some point.
+
+ /// List initialization failed at some point.
FK_ListInitializationFailed,
- /// \brief Initializer has a placeholder type which cannot be
+
+ /// Initializer has a placeholder type which cannot be
/// resolved by initialization.
FK_PlaceholderType,
- /// \brief Trying to take the address of a function that doesn't support
+
+ /// Trying to take the address of a function that doesn't support
/// having its address taken.
FK_AddressOfUnaddressableFunction,
- /// \brief List-copy-initialization chose an explicit constructor.
+
+ /// List-copy-initialization chose an explicit constructor.
FK_ExplicitConstructor,
};
private:
- /// \brief The reason why initialization failed.
+ /// The reason why initialization failed.
FailureKind Failure;
- /// \brief The failed result of overload resolution.
+ /// The failed result of overload resolution.
OverloadingResult FailedOverloadResult;
- /// \brief The candidate set created when initialization failed.
+ /// The candidate set created when initialization failed.
OverloadCandidateSet FailedCandidateSet;
- /// \brief The incomplete type that caused a failure.
+ /// The incomplete type that caused a failure.
QualType FailedIncompleteType;
- /// \brief The fixit that needs to be applied to make this initialization
+ /// The fixit that needs to be applied to make this initialization
/// succeed.
std::string ZeroInitializationFixit;
SourceLocation ZeroInitializationFixitLoc;
public:
- /// \brief Call for initializations are invalid but that would be valid
+ /// Call for initializations are invalid but that would be valid
/// zero initialzations if Fixit was applied.
void SetZeroInitializationFixit(const std::string& Fixit, SourceLocation L) {
ZeroInitializationFixit = Fixit;
@@ -935,13 +1095,12 @@ public:
}
private:
-
- /// \brief Prints a follow-up note that highlights the location of
+ /// Prints a follow-up note that highlights the location of
/// the initialized entity, if it's remote.
void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity);
public:
- /// \brief Try to perform initialization of the given entity, creating a
+ /// Try to perform initialization of the given entity, creating a
/// record of the steps required to perform the initialization.
///
/// The generated initialization sequence will either contain enough
@@ -972,7 +1131,7 @@ public:
~InitializationSequence();
- /// \brief Perform the actual initialization of the given entity based on
+ /// Perform the actual initialization of the given entity based on
/// the computed initialization sequence.
///
/// \param S the semantic analysis object.
@@ -999,7 +1158,7 @@ public:
MultiExprArg Args,
QualType *ResultType = nullptr);
- /// \brief Diagnose an potentially-invalid initialization sequence.
+ /// Diagnose an potentially-invalid initialization sequence.
///
/// \returns true if the initialization sequence was ill-formed,
/// false otherwise.
@@ -1008,37 +1167,39 @@ public:
const InitializationKind &Kind,
ArrayRef<Expr *> Args);
- /// \brief Determine the kind of initialization sequence computed.
+ /// Determine the kind of initialization sequence computed.
enum SequenceKind getKind() const { return SequenceKind; }
- /// \brief Set the kind of sequence computed.
+ /// Set the kind of sequence computed.
void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; }
- /// \brief Determine whether the initialization sequence is valid.
+ /// Determine whether the initialization sequence is valid.
explicit operator bool() const { return !Failed(); }
- /// \brief Determine whether the initialization sequence is invalid.
+ /// Determine whether the initialization sequence is invalid.
bool Failed() const { return SequenceKind == FailedSequence; }
- typedef SmallVectorImpl<Step>::const_iterator step_iterator;
+ using step_iterator = SmallVectorImpl<Step>::const_iterator;
+
step_iterator step_begin() const { return Steps.begin(); }
step_iterator step_end() const { return Steps.end(); }
- typedef llvm::iterator_range<step_iterator> step_range;
+ using step_range = llvm::iterator_range<step_iterator>;
+
step_range steps() const { return {step_begin(), step_end()}; }
- /// \brief Determine whether this initialization is a direct reference
+ /// Determine whether this initialization is a direct reference
/// binding (C++ [dcl.init.ref]).
bool isDirectReferenceBinding() const;
- /// \brief Determine whether this initialization failed due to an ambiguity.
+ /// Determine whether this initialization failed due to an ambiguity.
bool isAmbiguous() const;
- /// \brief Determine whether this initialization is direct call to a
+ /// Determine whether this initialization is direct call to a
/// constructor.
bool isConstructorInitialization() const;
- /// \brief Returns whether the last step in this initialization sequence is a
+ /// Returns whether the last step in this initialization sequence is a
/// narrowing conversion, defined by C++0x [dcl.init.list]p7.
///
/// If this function returns true, *isInitializerConstant will be set to
@@ -1049,7 +1210,7 @@ public:
bool *isInitializerConstant,
APValue *ConstantValue) const;
- /// \brief Add a new step in the initialization that resolves the address
+ /// Add a new step in the initialization that resolves the address
/// of an overloaded function to a specific function declaration.
///
/// \param Function the function to which the overloaded function reference
@@ -1058,7 +1219,7 @@ public:
DeclAccessPair Found,
bool HadMultipleCandidates);
- /// \brief Add a new step in the initialization that performs a derived-to-
+ /// Add a new step in the initialization that performs a derived-to-
/// base cast.
///
/// \param BaseType the base type to which we will be casting.
@@ -1068,14 +1229,14 @@ public:
void AddDerivedToBaseCastStep(QualType BaseType,
ExprValueKind Category);
- /// \brief Add a new step binding a reference to an object.
+ /// Add a new step binding a reference to an object.
///
/// \param BindingTemporary True if we are binding a reference to a temporary
/// object (thereby extending its lifetime); false if we are binding to an
/// lvalue or an lvalue treated as an rvalue.
void AddReferenceBindingStep(QualType T, bool BindingTemporary);
- /// \brief Add a new step that makes an extraneous copy of the input
+ /// Add a new step that makes an extraneous copy of the input
/// to a temporary of the same class type.
///
/// This extraneous copy only occurs during reference binding in
@@ -1087,40 +1248,40 @@ public:
/// \param T The type of the temporary being created.
void AddExtraneousCopyToTemporary(QualType T);
- /// \brief Add a new step that makes a copy of the input to an object of
+ /// Add a new step that makes a copy of the input to an object of
/// the given type, as the final step in class copy-initialization.
void AddFinalCopy(QualType T);
- /// \brief Add a new step invoking a conversion function, which is either
+ /// Add a new step invoking a conversion function, which is either
/// a constructor or a conversion function.
void AddUserConversionStep(FunctionDecl *Function,
DeclAccessPair FoundDecl,
QualType T,
bool HadMultipleCandidates);
- /// \brief Add a new step that performs a qualification conversion to the
+ /// Add a new step that performs a qualification conversion to the
/// given type.
void AddQualificationConversionStep(QualType Ty,
ExprValueKind Category);
- /// \brief Add a new step that performs conversion from non-atomic to atomic
+ /// Add a new step that performs conversion from non-atomic to atomic
/// type.
void AddAtomicConversionStep(QualType Ty);
- /// \brief Add a new step that performs a load of the given type.
+ /// Add a new step that performs a load of the given type.
///
/// Although the term "LValueToRValue" is conventional, this applies to both
/// lvalues and xvalues.
void AddLValueToRValueStep(QualType Ty);
- /// \brief Add a new step that applies an implicit conversion sequence.
+ /// Add a new step that applies an implicit conversion sequence.
void AddConversionSequenceStep(const ImplicitConversionSequence &ICS,
QualType T, bool TopLevelOfInitList = false);
- /// \brief Add a list-initialization step.
+ /// Add a list-initialization step.
void AddListInitializationStep(QualType T);
- /// \brief Add a constructor-initialization step.
+ /// Add a constructor-initialization step.
///
/// \param FromInitList The constructor call is syntactically an initializer
/// list.
@@ -1131,59 +1292,59 @@ public:
bool HadMultipleCandidates,
bool FromInitList, bool AsInitList);
- /// \brief Add a zero-initialization step.
+ /// Add a zero-initialization step.
void AddZeroInitializationStep(QualType T);
- /// \brief Add a C assignment step.
+ /// Add a C assignment step.
//
// FIXME: It isn't clear whether this should ever be needed;
// ideally, we would handle everything needed in C in the common
// path. However, that isn't the case yet.
void AddCAssignmentStep(QualType T);
- /// \brief Add a string init step.
+ /// Add a string init step.
void AddStringInitStep(QualType T);
- /// \brief Add an Objective-C object conversion step, which is
+ /// Add an Objective-C object conversion step, which is
/// always a no-op.
void AddObjCObjectConversionStep(QualType T);
- /// \brief Add an array initialization loop step.
+ /// Add an array initialization loop step.
void AddArrayInitLoopStep(QualType T, QualType EltTy);
- /// \brief Add an array initialization step.
+ /// Add an array initialization step.
void AddArrayInitStep(QualType T, bool IsGNUExtension);
- /// \brief Add a parenthesized array initialization step.
+ /// Add a parenthesized array initialization step.
void AddParenthesizedArrayInitStep(QualType T);
- /// \brief Add a step to pass an object by indirect copy-restore.
+ /// Add a step to pass an object by indirect copy-restore.
void AddPassByIndirectCopyRestoreStep(QualType T, bool shouldCopy);
- /// \brief Add a step to "produce" an Objective-C object (by
+ /// Add a step to "produce" an Objective-C object (by
/// retaining it).
void AddProduceObjCObjectStep(QualType T);
- /// \brief Add a step to construct a std::initializer_list object from an
+ /// Add a step to construct a std::initializer_list object from an
/// initializer list.
void AddStdInitializerListConstructionStep(QualType T);
- /// \brief Add a step to initialize an OpenCL sampler from an integer
+ /// Add a step to initialize an OpenCL sampler from an integer
/// constant.
void AddOCLSamplerInitStep(QualType T);
- /// \brief Add a step to initialize an OpenCL event_t from a NULL
+ /// Add a step to initialize an OpenCL event_t from a NULL
/// constant.
void AddOCLZeroEventStep(QualType T);
- /// \brief Add a step to initialize an OpenCL queue_t from 0.
+ /// Add a step to initialize an OpenCL queue_t from 0.
void AddOCLZeroQueueStep(QualType T);
- /// \brief Add steps to unwrap a initializer list for a reference around a
+ /// Add steps to unwrap a initializer list for a reference around a
/// single element and rewrap it at the end.
void RewrapReferenceInitList(QualType T, InitListExpr *Syntactic);
- /// \brief Note that this initialization sequence failed.
+ /// Note that this initialization sequence failed.
void SetFailed(FailureKind Failure) {
SequenceKind = FailedSequence;
this->Failure = Failure;
@@ -1191,44 +1352,44 @@ public:
"Incomplete type failure requires a type!");
}
- /// \brief Note that this initialization sequence failed due to failed
+ /// Note that this initialization sequence failed due to failed
/// overload resolution.
void SetOverloadFailure(FailureKind Failure, OverloadingResult Result);
- /// \brief Retrieve a reference to the candidate set when overload
+ /// Retrieve a reference to the candidate set when overload
/// resolution fails.
OverloadCandidateSet &getFailedCandidateSet() {
return FailedCandidateSet;
}
- /// \brief Get the overloading result, for when the initialization
+ /// Get the overloading result, for when the initialization
/// sequence failed due to a bad overload.
OverloadingResult getFailedOverloadResult() const {
return FailedOverloadResult;
}
- /// \brief Note that this initialization sequence failed due to an
+ /// Note that this initialization sequence failed due to an
/// incomplete type.
void setIncompleteTypeFailure(QualType IncompleteType) {
FailedIncompleteType = IncompleteType;
SetFailed(FK_Incomplete);
}
- /// \brief Determine why initialization failed.
+ /// Determine why initialization failed.
FailureKind getFailureKind() const {
assert(Failed() && "Not an initialization failure!");
return Failure;
}
- /// \brief Dump a representation of this initialization sequence to
+ /// Dump a representation of this initialization sequence to
/// the given stream, for debugging purposes.
void dump(raw_ostream &OS) const;
- /// \brief Dump a representation of this initialization sequence to
+ /// Dump a representation of this initialization sequence to
/// standard error, for debugging purposes.
void dump() const;
};
-} // end namespace clang
+} // namespace clang
#endif // LLVM_CLANG_SEMA_INITIALIZATION_H
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
index 546df8842a356..c06952064dd9e 100644
--- a/include/clang/Sema/Lookup.h
+++ b/include/clang/Sema/Lookup.h
@@ -1,4 +1,4 @@
-//===--- Lookup.h - Classes for name lookup ---------------------*- C++ -*-===//
+//===- Lookup.h - Classes for name lookup -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,14 +15,29 @@
#ifndef LLVM_CLANG_SEMA_LOOKUP_H
#define LLVM_CLANG_SEMA_LOOKUP_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Sema.h"
-
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
+#include <utility>
namespace clang {
-/// @brief Represents the results of name lookup.
+class CXXBasePaths;
+
+/// Represents the results of name lookup.
///
/// An instance of the LookupResult class captures the results of a
/// single name lookup, which can return no result (nothing found),
@@ -32,28 +47,28 @@ namespace clang {
class LookupResult {
public:
enum LookupResultKind {
- /// @brief No entity found met the criteria.
+ /// No entity found met the criteria.
NotFound = 0,
- /// @brief No entity found met the criteria within the current
+ /// No entity found met the criteria within the current
/// instantiation,, but there were dependent base classes of the
/// current instantiation that could not be searched.
NotFoundInCurrentInstantiation,
- /// @brief Name lookup found a single declaration that met the
+ /// Name lookup found a single declaration that met the
/// criteria. getFoundDecl() will return this declaration.
Found,
- /// @brief Name lookup found a set of overloaded functions that
+ /// Name lookup found a set of overloaded functions that
/// met the criteria.
FoundOverloaded,
- /// @brief Name lookup found an unresolvable value declaration
+ /// Name lookup found an unresolvable value declaration
/// and cannot yet complete. This only happens in C++ dependent
/// contexts with dependent using declarations.
FoundUnresolvedValue,
- /// @brief Name lookup results in an ambiguity; use
+ /// Name lookup results in an ambiguity; use
/// getAmbiguityKind to figure out what kind of ambiguity
/// we have.
Ambiguous
@@ -126,25 +141,15 @@ public:
Temporary
};
- typedef UnresolvedSetImpl::iterator iterator;
+ using iterator = UnresolvedSetImpl::iterator;
LookupResult(Sema &SemaRef, const DeclarationNameInfo &NameInfo,
Sema::LookupNameKind LookupKind,
Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
- : ResultKind(NotFound),
- Paths(nullptr),
- NamingClass(nullptr),
- SemaPtr(&SemaRef),
- NameInfo(NameInfo),
- LookupKind(LookupKind),
- IDNS(0),
- Redecl(Redecl != Sema::NotForRedeclaration),
- ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
- HideTags(true),
- Diagnose(Redecl == Sema::NotForRedeclaration),
- AllowHidden(false),
- Shadowed(false)
- {
+ : SemaPtr(&SemaRef), NameInfo(NameInfo), LookupKind(LookupKind),
+ Redecl(Redecl != Sema::NotForRedeclaration),
+ ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
+ Diagnose(Redecl == Sema::NotForRedeclaration) {
configure();
}
@@ -154,20 +159,10 @@ public:
LookupResult(Sema &SemaRef, DeclarationName Name,
SourceLocation NameLoc, Sema::LookupNameKind LookupKind,
Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
- : ResultKind(NotFound),
- Paths(nullptr),
- NamingClass(nullptr),
- SemaPtr(&SemaRef),
- NameInfo(Name, NameLoc),
- LookupKind(LookupKind),
- IDNS(0),
- Redecl(Redecl != Sema::NotForRedeclaration),
- ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
- HideTags(true),
- Diagnose(Redecl == Sema::NotForRedeclaration),
- AllowHidden(false),
- Shadowed(false)
- {
+ : SemaPtr(&SemaRef), NameInfo(Name, NameLoc), LookupKind(LookupKind),
+ Redecl(Redecl != Sema::NotForRedeclaration),
+ ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
+ Diagnose(Redecl == Sema::NotForRedeclaration) {
configure();
}
@@ -175,20 +170,10 @@ public:
/// using the information from another result. Diagnostics are always
/// disabled.
LookupResult(TemporaryToken _, const LookupResult &Other)
- : ResultKind(NotFound),
- Paths(nullptr),
- NamingClass(nullptr),
- SemaPtr(Other.SemaPtr),
- NameInfo(Other.NameInfo),
- LookupKind(Other.LookupKind),
- IDNS(Other.IDNS),
- Redecl(Other.Redecl),
- ExternalRedecl(Other.ExternalRedecl),
- HideTags(Other.HideTags),
- Diagnose(false),
- AllowHidden(Other.AllowHidden),
- Shadowed(false)
- {}
+ : SemaPtr(Other.SemaPtr), NameInfo(Other.NameInfo),
+ LookupKind(Other.LookupKind), IDNS(Other.IDNS), Redecl(Other.Redecl),
+ ExternalRedecl(Other.ExternalRedecl), HideTags(Other.HideTags),
+ AllowHidden(Other.AllowHidden) {}
// FIXME: Remove these deleted methods once the default build includes
// -Wdeprecated.
@@ -213,6 +198,7 @@ public:
Other.Paths = nullptr;
Other.Diagnose = false;
}
+
LookupResult &operator=(LookupResult &&Other) {
ResultKind = std::move(Other.ResultKind);
Ambiguity = std::move(Other.Ambiguity);
@@ -246,7 +232,7 @@ public:
return NameInfo;
}
- /// \brief Sets the name info to look up.
+ /// Sets the name info to look up.
void setLookupNameInfo(const DeclarationNameInfo &NameInfo) {
this->NameInfo = NameInfo;
}
@@ -256,7 +242,7 @@ public:
return NameInfo.getName();
}
- /// \brief Sets the name to look up.
+ /// Sets the name to look up.
void setLookupName(DeclarationName Name) {
NameInfo.setName(Name);
}
@@ -282,13 +268,13 @@ public:
Redecl ? Sema::ForVisibleRedeclaration : Sema::NotForRedeclaration;
}
- /// \brief Specify whether hidden declarations are visible, e.g.,
+ /// Specify whether hidden declarations are visible, e.g.,
/// for recovery reasons.
void setAllowHidden(bool AH) {
AllowHidden = AH;
}
- /// \brief Determine whether this lookup is permitted to see hidden
+ /// Determine whether this lookup is permitted to see hidden
/// declarations, such as those in modules that have not yet been imported.
bool isHiddenDeclarationVisible(NamedDecl *ND) const {
return AllowHidden ||
@@ -338,16 +324,16 @@ public:
iterator begin() const { return iterator(Decls.begin()); }
iterator end() const { return iterator(Decls.end()); }
- /// \brief Return true if no decls were found
+ /// Return true if no decls were found
bool empty() const { return Decls.empty(); }
- /// \brief Return the base paths structure that's associated with
+ /// Return the base paths structure that's associated with
/// these results, or null if none is.
CXXBasePaths *getBasePaths() const {
return Paths;
}
- /// \brief Determine whether the given declaration is visible to the
+ /// Determine whether the given declaration is visible to the
/// program.
static bool isVisible(Sema &SemaRef, NamedDecl *D) {
// If this declaration is not hidden, it's visible.
@@ -359,7 +345,7 @@ public:
return isVisibleSlow(SemaRef, D);
}
- /// \brief Retrieve the accepted (re)declaration of the given declaration,
+ /// Retrieve the accepted (re)declaration of the given declaration,
/// if there is one.
NamedDecl *getAcceptableDecl(NamedDecl *D) const {
if (!D->isInIdentifierNamespace(IDNS))
@@ -376,18 +362,18 @@ private:
NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const;
public:
- /// \brief Returns the identifier namespace mask for this lookup.
+ /// Returns the identifier namespace mask for this lookup.
unsigned getIdentifierNamespace() const {
return IDNS;
}
- /// \brief Returns whether these results arose from performing a
+ /// Returns whether these results arose from performing a
/// lookup into a class.
bool isClassLookup() const {
return NamingClass != nullptr;
}
- /// \brief Returns the 'naming class' for this lookup, i.e. the
+ /// Returns the 'naming class' for this lookup, i.e. the
/// class which was looked into to find these results.
///
/// C++0x [class.access.base]p5:
@@ -407,72 +393,72 @@ public:
return NamingClass;
}
- /// \brief Sets the 'naming class' for this lookup.
+ /// Sets the 'naming class' for this lookup.
void setNamingClass(CXXRecordDecl *Record) {
NamingClass = Record;
}
- /// \brief Returns the base object type associated with this lookup;
+ /// Returns the base object type associated with this lookup;
/// important for [class.protected]. Most lookups do not have an
/// associated base object.
QualType getBaseObjectType() const {
return BaseObjectType;
}
- /// \brief Sets the base object type for this lookup.
+ /// Sets the base object type for this lookup.
void setBaseObjectType(QualType T) {
BaseObjectType = T;
}
- /// \brief Add a declaration to these results with its natural access.
+ /// Add a declaration to these results with its natural access.
/// Does not test the acceptance criteria.
void addDecl(NamedDecl *D) {
addDecl(D, D->getAccess());
}
- /// \brief Add a declaration to these results with the given access.
+ /// Add a declaration to these results with the given access.
/// Does not test the acceptance criteria.
void addDecl(NamedDecl *D, AccessSpecifier AS) {
Decls.addDecl(D, AS);
ResultKind = Found;
}
- /// \brief Add all the declarations from another set of lookup
+ /// Add all the declarations from another set of lookup
/// results.
void addAllDecls(const LookupResult &Other) {
Decls.append(Other.Decls.begin(), Other.Decls.end());
ResultKind = Found;
}
- /// \brief Determine whether no result was found because we could not
+ /// Determine whether no result was found because we could not
/// search into dependent base classes of the current instantiation.
bool wasNotFoundInCurrentInstantiation() const {
return ResultKind == NotFoundInCurrentInstantiation;
}
- /// \brief Note that while no result was found in the current instantiation,
+ /// Note that while no result was found in the current instantiation,
/// there were dependent base classes that could not be searched.
void setNotFoundInCurrentInstantiation() {
assert(ResultKind == NotFound && Decls.empty());
ResultKind = NotFoundInCurrentInstantiation;
}
- /// \brief Determine whether the lookup result was shadowed by some other
+ /// Determine whether the lookup result was shadowed by some other
/// declaration that lookup ignored.
bool isShadowed() const { return Shadowed; }
- /// \brief Note that we found and ignored a declaration while performing
+ /// Note that we found and ignored a declaration while performing
/// lookup.
void setShadowed() { Shadowed = true; }
- /// \brief Resolves the result kind of the lookup, possibly hiding
+ /// Resolves the result kind of the lookup, possibly hiding
/// decls.
///
/// This should be called in any environment where lookup might
/// generate multiple lookup results.
void resolveKind();
- /// \brief Re-resolves the result kind of the lookup after a set of
+ /// Re-resolves the result kind of the lookup after a set of
/// removals has been performed.
void resolveKindAfterFilter() {
if (Decls.empty()) {
@@ -512,7 +498,7 @@ public:
return dyn_cast<DeclClass>(getFoundDecl());
}
- /// \brief Fetch the unique decl found by this lookup. Asserts
+ /// Fetch the unique decl found by this lookup. Asserts
/// that one was found.
///
/// This is intended for users who have examined the result kind
@@ -529,31 +515,31 @@ public:
return *begin();
}
- /// \brief Asks if the result is a single tag decl.
+ /// Asks if the result is a single tag decl.
bool isSingleTagDecl() const {
return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
}
- /// \brief Make these results show that the name was found in
+ /// Make these results show that the name was found in
/// base classes of different types.
///
/// The given paths object is copied and invalidated.
void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
- /// \brief Make these results show that the name was found in
+ /// Make these results show that the name was found in
/// distinct base classes of the same type.
///
/// The given paths object is copied and invalidated.
void setAmbiguousBaseSubobjects(CXXBasePaths &P);
- /// \brief Make these results show that the name was found in
+ /// Make these results show that the name was found in
/// different contexts and a tag decl was hidden by an ordinary
/// decl in a different context.
void setAmbiguousQualifiedTagHiding() {
setAmbiguous(AmbiguousTagHiding);
}
- /// \brief Clears out any current state.
+ /// Clears out any current state.
void clear() {
ResultKind = NotFound;
Decls.clear();
@@ -563,7 +549,7 @@ public:
Shadowed = false;
}
- /// \brief Clears out any current state and re-initializes for a
+ /// Clears out any current state and re-initializes for a
/// different kind of lookup.
void clear(Sema::LookupNameKind Kind) {
clear();
@@ -571,7 +557,7 @@ public:
configure();
}
- /// \brief Change this lookup's redeclaration kind.
+ /// Change this lookup's redeclaration kind.
void setRedeclarationKind(Sema::RedeclarationKind RK) {
Redecl = (RK != Sema::NotForRedeclaration);
ExternalRedecl = (RK == Sema::ForExternalRedeclaration);
@@ -610,7 +596,7 @@ public:
return NameInfo.getLoc();
}
- /// \brief Get the Sema object that this lookup result is searching
+ /// Get the Sema object that this lookup result is searching
/// with.
Sema &getSema() const { return *SemaPtr; }
@@ -618,15 +604,14 @@ public:
/// filtering out results. The results returned are possibly
/// sugared.
class Filter {
+ friend class LookupResult;
+
LookupResult &Results;
LookupResult::iterator I;
- bool Changed;
- bool CalledDone;
+ bool Changed = false;
+ bool CalledDone = false;
- friend class LookupResult;
- Filter(LookupResult &Results)
- : Results(Results), I(Results.begin()), Changed(false), CalledDone(false)
- {}
+ Filter(LookupResult &Results) : Results(Results), I(Results.begin()) {}
public:
Filter(Filter &&F)
@@ -634,6 +619,7 @@ public:
CalledDone(F.CalledDone) {
F.CalledDone = true;
}
+
~Filter() {
assert(CalledDone &&
"LookupResult::Filter destroyed without done() call");
@@ -722,11 +708,11 @@ private:
static void deletePaths(CXXBasePaths *);
// Results.
- LookupResultKind ResultKind;
+ LookupResultKind ResultKind = NotFound;
AmbiguityKind Ambiguity; // ill-defined unless ambiguous
UnresolvedSet<8> Decls;
- CXXBasePaths *Paths;
- CXXRecordDecl *NamingClass;
+ CXXBasePaths *Paths = nullptr;
+ CXXRecordDecl *NamingClass = nullptr;
QualType BaseObjectType;
// Parameters.
@@ -734,27 +720,27 @@ private:
DeclarationNameInfo NameInfo;
SourceRange NameContextRange;
Sema::LookupNameKind LookupKind;
- unsigned IDNS; // set by configure()
+ unsigned IDNS = 0; // set by configure()
bool Redecl;
bool ExternalRedecl;
- /// \brief True if tag declarations should be hidden if non-tags
+ /// True if tag declarations should be hidden if non-tags
/// are present
- bool HideTags;
+ bool HideTags = true;
- bool Diagnose;
+ bool Diagnose = false;
- /// \brief True if we should allow hidden declarations to be 'visible'.
- bool AllowHidden;
+ /// True if we should allow hidden declarations to be 'visible'.
+ bool AllowHidden = false;
- /// \brief True if the found declarations were shadowed by some other
+ /// True if the found declarations were shadowed by some other
/// declaration that we skipped. This only happens when \c LookupKind
/// is \c LookupRedeclarationWithLinkage.
- bool Shadowed;
+ bool Shadowed = false;
};
-/// \brief Consumes visible declarations found when searching for
+/// Consumes visible declarations found when searching for
/// all visible names within a given scope or context.
///
/// This abstract class is meant to be subclassed by clients of \c
@@ -762,15 +748,15 @@ private:
/// FoundDecl() function to process declarations as they are found.
class VisibleDeclConsumer {
public:
- /// \brief Destroys the visible declaration consumer.
+ /// Destroys the visible declaration consumer.
virtual ~VisibleDeclConsumer();
- /// \brief Determine whether hidden declarations (from unimported
+ /// Determine whether hidden declarations (from unimported
/// modules) should be given to this consumer. By default, they
/// are not included.
virtual bool includeHiddenDecls() const;
- /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a
+ /// Invoked each time \p Sema::LookupVisibleDecls() finds a
/// declaration visible from the current scope or context.
///
/// \param ND the declaration found.
@@ -784,9 +770,15 @@ public:
/// class of the context we searched.
virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
bool InBaseClass) = 0;
+
+ /// Callback to inform the client that Sema entered into a new context
+ /// to find a visible declaration.
+ //
+ /// \param Ctx the context which Sema entered.
+ virtual void EnteredContext(DeclContext *Ctx) {}
};
-/// \brief A class for storing results from argument-dependent lookup.
+/// A class for storing results from argument-dependent lookup.
class ADLResult {
private:
/// A map from canonical decls to the 'most recent' decl.
@@ -807,13 +799,13 @@ public:
Decls.erase(cast<NamedDecl>(D->getCanonicalDecl()));
}
- typedef llvm::mapped_iterator<decltype(Decls)::iterator, select_second>
- iterator;
+ using iterator =
+ llvm::mapped_iterator<decltype(Decls)::iterator, select_second>;
iterator begin() { return iterator(Decls.begin(), select_second()); }
iterator end() { return iterator(Decls.end(), select_second()); }
};
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SEMA_LOOKUP_H
diff --git a/include/clang/Sema/LoopHint.h b/include/clang/Sema/LoopHint.h
index c8b2ee845e590..171435e69bc8a 100644
--- a/include/clang/Sema/LoopHint.h
+++ b/include/clang/Sema/LoopHint.h
@@ -12,12 +12,12 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Sema/AttributeList.h"
#include "clang/Sema/Ownership.h"
+#include "clang/Sema/ParsedAttr.h"
namespace clang {
-/// \brief Loop optimization hint for loop and unroll pragmas.
+/// Loop optimization hint for loop and unroll pragmas.
struct LoopHint {
// Source range of the directive.
SourceRange Range;
diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h
index 1d681a00552fc..4c242c89f3f4b 100644
--- a/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -33,7 +33,7 @@ namespace clang {
class VarDecl;
-/// \brief An abstract interface that should be implemented by
+/// An abstract interface that should be implemented by
/// external AST sources that also provide information for semantic
/// analysis.
class MultiplexExternalSemaSource : public ExternalSemaSource {
@@ -43,7 +43,7 @@ private:
public:
- ///\brief Constructs a new multiplexing external sema source and appends the
+ ///Constructs a new multiplexing external sema source and appends the
/// given element to it.
///
///\param[in] s1 - A non-null (old) ExternalSemaSource.
@@ -53,7 +53,7 @@ public:
~MultiplexExternalSemaSource() override;
- ///\brief Appends new source to the source list.
+ ///Appends new source to the source list.
///
///\param[in] source - An ExternalSemaSource.
///
@@ -63,45 +63,45 @@ public:
// ExternalASTSource.
//===--------------------------------------------------------------------===//
- /// \brief Resolve a declaration ID into a declaration, potentially
+ /// Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
Decl *GetExternalDecl(uint32_t ID) override;
- /// \brief Complete the redeclaration chain if it's been extended since the
+ /// Complete the redeclaration chain if it's been extended since the
/// previous generation of the AST source.
void CompleteRedeclChain(const Decl *D) override;
- /// \brief Resolve a selector ID into a selector.
+ /// Resolve a selector ID into a selector.
Selector GetExternalSelector(uint32_t ID) override;
- /// \brief Returns the number of selectors known to the external AST
+ /// Returns the number of selectors known to the external AST
/// source.
uint32_t GetNumExternalSelectors() override;
- /// \brief Resolve the offset of a statement in the decl stream into
+ /// Resolve the offset of a statement in the decl stream into
/// a statement.
Stmt *GetExternalDeclStmt(uint64_t Offset) override;
- /// \brief Resolve the offset of a set of C++ base specifiers in the decl
+ /// Resolve the offset of a set of C++ base specifiers in the decl
/// stream into an array of specifiers.
CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
- /// \brief Resolve a handle to a list of ctor initializers into the list of
+ /// Resolve a handle to a list of ctor initializers into the list of
/// initializers themselves.
CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override;
ExtKind hasExternalDefinitions(const Decl *D) override;
- /// \brief Find all declarations with the given name in the
+ /// Find all declarations with the given name in the
/// given context.
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;
- /// \brief Ensures that the table of all visible declarations inside this
+ /// Ensures that the table of all visible declarations inside this
/// context is up to date.
void completeVisibleDeclsMap(const DeclContext *DC) override;
- /// \brief Finds all declarations lexically contained within the given
+ /// Finds all declarations lexically contained within the given
/// DeclContext, after applying an optional filter predicate.
///
/// \param IsKindWeWant a predicate function that returns true if the passed
@@ -111,17 +111,17 @@ public:
llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
SmallVectorImpl<Decl *> &Result) override;
- /// \brief Get the decls that are contained in a file in the Offset/Length
+ /// 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.
void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
SmallVectorImpl<Decl *> &Decls) override;
- /// \brief Gives the external AST source an opportunity to complete
+ /// Gives the external AST source an opportunity to complete
/// an incomplete type.
void CompleteType(TagDecl *Tag) override;
- /// \brief Gives the external AST source an opportunity to complete an
+ /// 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
@@ -129,28 +129,32 @@ public:
/// \c ObjCInterfaceDecl::setExternallyCompleted().
void CompleteType(ObjCInterfaceDecl *Class) override;
- /// \brief Loads comment ranges.
+ /// Loads comment ranges.
void ReadComments() override;
- /// \brief Notify ExternalASTSource that we started deserialization of
+ /// 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.
void StartedDeserializing() override;
- /// \brief Notify ExternalASTSource that we finished the deserialization of
+ /// Notify ExternalASTSource that we finished the deserialization of
/// a decl or type. Must be paired with StartedDeserializing.
void FinishedDeserializing() override;
- /// \brief Function that will be invoked when we begin parsing a new
+ /// Function that will be invoked when we begin parsing a new
/// translation unit involving this external AST source.
void StartTranslationUnit(ASTConsumer *Consumer) override;
- /// \brief Print any statistics that have been gathered regarding
+ /// Print any statistics that have been gathered regarding
/// the external AST source.
void PrintStats() override;
-
-
- /// \brief Perform layout on the given record.
+
+ /// Retrieve the module that corresponds to the given module ID.
+ Module *getModule(unsigned ID) override;
+
+ bool DeclIsFromPCHWithObjectFile(const Decl *D) override;
+
+ /// Perform layout on the given record.
///
/// This routine allows the external AST source to provide an specific
/// layout for a record, overriding the layout that would normally be
@@ -193,15 +197,15 @@ public:
// ExternalSemaSource.
//===--------------------------------------------------------------------===//
- /// \brief Initialize the semantic source with the Sema instance
+ /// Initialize the semantic source with the Sema instance
/// being used to perform semantic analysis on the abstract syntax
/// tree.
void InitializeSema(Sema &S) override;
- /// \brief Inform the semantic consumer that Sema is no longer available.
+ /// Inform the semantic consumer that Sema is no longer available.
void ForgetSema() override;
- /// \brief Load the contents of the global method pool for a given
+ /// Load the contents of the global method pool for a given
/// selector.
void ReadMethodPool(Selector Sel) override;
@@ -209,12 +213,12 @@ public:
/// selector if necessary.
void updateOutOfDateSelector(Selector Sel) override;
- /// \brief Load the set of namespaces that are known to the external source,
+ /// Load the set of namespaces that are known to the external source,
/// which will be used during typo correction.
void
ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces) override;
- /// \brief Load the set of used but not defined functions or variables with
+ /// Load the set of used but not defined functions or variables with
/// internal linkage, or used but not defined inline functions.
void ReadUndefinedButUsed(
llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) override;
@@ -223,7 +227,7 @@ public:
FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &
Exprs) override;
- /// \brief Do last resort, unqualified lookup on a LookupResult that
+ /// Do last resort, unqualified lookup on a LookupResult that
/// Sema cannot find.
///
/// \param R a LookupResult that is being recovered.
@@ -233,7 +237,7 @@ public:
/// \return true to tell Sema to recover using the LookupResult.
bool LookupUnqualified(LookupResult &R, Scope *S) override;
- /// \brief Read the set of tentative definitions known to the external Sema
+ /// Read the set of tentative definitions known to the external Sema
/// source.
///
/// The external source should append its own tentative definitions to the
@@ -242,7 +246,7 @@ public:
/// introduce the same declarations repeatedly.
void ReadTentativeDefinitions(SmallVectorImpl<VarDecl*> &Defs) override;
- /// \brief Read the set of unused file-scope declarations known to the
+ /// Read the set of unused file-scope declarations known to the
/// external Sema source.
///
/// The external source should append its own unused, filed-scope to the
@@ -252,7 +256,7 @@ public:
void ReadUnusedFileScopedDecls(
SmallVectorImpl<const DeclaratorDecl*> &Decls) override;
- /// \brief Read the set of delegating constructors known to the
+ /// Read the set of delegating constructors known to the
/// external Sema source.
///
/// The external source should append its own delegating constructors to the
@@ -262,7 +266,7 @@ public:
void ReadDelegatingConstructors(
SmallVectorImpl<CXXConstructorDecl*> &Decls) override;
- /// \brief Read the set of ext_vector type declarations known to the
+ /// Read the set of ext_vector type declarations known to the
/// external Sema source.
///
/// The external source should append its own ext_vector type declarations to
@@ -271,7 +275,7 @@ public:
/// introduce the same declarations repeatedly.
void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl*> &Decls) override;
- /// \brief Read the set of potentially unused typedefs known to the source.
+ /// Read the set of potentially unused typedefs known to the source.
///
/// The external source should append its own potentially unused local
/// typedefs to the given vector of declarations. Note that this routine may
@@ -280,7 +284,7 @@ public:
void ReadUnusedLocalTypedefNameCandidates(
llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override;
- /// \brief Read the set of referenced selectors known to the
+ /// Read the set of referenced selectors known to the
/// external Sema source.
///
/// The external source should append its own referenced selectors to the
@@ -290,7 +294,7 @@ public:
void ReadReferencedSelectors(SmallVectorImpl<std::pair<Selector,
SourceLocation> > &Sels) override;
- /// \brief Read the set of weak, undeclared identifiers known to the
+ /// Read the set of weak, undeclared identifiers known to the
/// external Sema source.
///
/// The external source should append its own weak, undeclared identifiers to
@@ -300,14 +304,14 @@ public:
void ReadWeakUndeclaredIdentifiers(
SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) override;
- /// \brief Read the set of used vtables known to the external Sema source.
+ /// Read the set of used vtables known to the external Sema source.
///
/// The external source should append its own used vtables to the given
/// vector. Note that this routine may be invoked multiple times; the external
/// source should take care not to introduce the same vtables repeatedly.
void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override;
- /// \brief Read the set of pending instantiations known to the external
+ /// Read the set of pending instantiations known to the external
/// Sema source.
///
/// The external source should append its own pending instantiations to the
@@ -317,7 +321,7 @@ public:
void ReadPendingInstantiations(
SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending) override;
- /// \brief Read the set of late parsed template functions for this source.
+ /// Read the set of late parsed template functions for this source.
///
/// The external source should insert its own late parsed template functions
/// into the map. Note that this routine may be invoked multiple times; the
@@ -336,7 +340,7 @@ public:
bool EnteringContext,
const ObjCObjectPointerType *OPT) override;
- /// \brief Produces a diagnostic note if one of the attached sources
+ /// Produces a diagnostic note if one of the attached sources
/// contains a complete definition for \p T. Queries the sources in list
/// order until the first one claims that a diagnostic was produced.
///
diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h
index 80ccd363d2725..d0af4d15fb9f3 100644
--- a/include/clang/Sema/ObjCMethodList.h
+++ b/include/clang/Sema/ObjCMethodList.h
@@ -21,13 +21,13 @@ namespace clang {
class ObjCMethodDecl;
-/// \brief a linked list of methods with the same selector name but different
+/// a linked list of methods with the same selector name but different
/// signatures.
struct ObjCMethodList {
// NOTE: If you add any members to this struct, make sure to serialize them.
- /// \brief If there is more than one decl with this signature.
+ /// If there is more than one decl with this signature.
llvm::PointerIntPair<ObjCMethodDecl *, 1> MethodAndHasMoreThanOneDecl;
- /// \brief The next list object and 2 bits for extra info.
+ /// The next list object and 2 bits for extra info.
llvm::PointerIntPair<ObjCMethodList *, 2> NextAndExtraBits;
ObjCMethodList() { }
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 05cfe53666ca9..f75faf049625d 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -1,4 +1,4 @@
-//===--- Overload.h - C++ Overloading ---------------------------*- C++ -*-===//
+//===- Overload.h - C++ Overloading -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,32 +16,51 @@
#define LLVM_CLANG_SEMA_OVERLOAD_H
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
-#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/SemaFixItUtils.h"
#include "clang/Sema/TemplateDeduction.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <utility>
namespace clang {
- class ASTContext;
- class CXXConstructorDecl;
- class CXXConversionDecl;
- class FunctionDecl;
- class Sema;
+
+class APValue;
+class ASTContext;
+class Sema;
/// OverloadingResult - Capture the result of performing overload
/// resolution.
enum OverloadingResult {
- OR_Success, ///< Overload resolution succeeded.
- OR_No_Viable_Function, ///< No viable function found.
- OR_Ambiguous, ///< Ambiguous candidates found.
- OR_Deleted ///< Succeeded, but refers to a deleted function.
+ /// Overload resolution succeeded.
+ OR_Success,
+
+ /// No viable function found.
+ OR_No_Viable_Function,
+
+ /// Ambiguous candidates found.
+ OR_Ambiguous,
+
+ /// Succeeded, but refers to a deleted function.
+ OR_Deleted
};
enum OverloadCandidateDisplayKind {
@@ -55,39 +74,95 @@ namespace clang {
/// ImplicitConversionKind - The kind of implicit conversion used to
/// convert an argument to a parameter's type. The enumerator values
- /// match with Table 9 of (C++ 13.3.3.1.1) and are listed such that
- /// better conversion kinds have smaller values.
+ /// match with the table titled 'Conversions' in [over.ics.scs] and are listed
+ /// such that better conversion kinds have smaller values.
enum ImplicitConversionKind {
- ICK_Identity = 0, ///< Identity conversion (no conversion)
- ICK_Lvalue_To_Rvalue, ///< Lvalue-to-rvalue conversion (C++ 4.1)
- ICK_Array_To_Pointer, ///< Array-to-pointer conversion (C++ 4.2)
- ICK_Function_To_Pointer, ///< Function-to-pointer (C++ 4.3)
- ICK_Function_Conversion, ///< Function pointer conversion (C++17 4.13)
- ICK_Qualification, ///< Qualification conversions (C++ 4.4)
- ICK_Integral_Promotion, ///< Integral promotions (C++ 4.5)
- ICK_Floating_Promotion, ///< Floating point promotions (C++ 4.6)
- ICK_Complex_Promotion, ///< Complex promotions (Clang extension)
- ICK_Integral_Conversion, ///< Integral conversions (C++ 4.7)
- ICK_Floating_Conversion, ///< Floating point conversions (C++ 4.8)
- ICK_Complex_Conversion, ///< Complex conversions (C99 6.3.1.6)
- ICK_Floating_Integral, ///< Floating-integral conversions (C++ 4.9)
- ICK_Pointer_Conversion, ///< Pointer conversions (C++ 4.10)
- ICK_Pointer_Member, ///< Pointer-to-member conversions (C++ 4.11)
- ICK_Boolean_Conversion, ///< Boolean conversions (C++ 4.12)
- ICK_Compatible_Conversion, ///< Conversions between compatible types in C99
- ICK_Derived_To_Base, ///< Derived-to-base (C++ [over.best.ics])
- ICK_Vector_Conversion, ///< Vector conversions
- ICK_Vector_Splat, ///< A vector splat from an arithmetic type
- ICK_Complex_Real, ///< Complex-real conversions (C99 6.3.1.7)
- ICK_Block_Pointer_Conversion, ///< Block Pointer conversions
- ICK_TransparentUnionConversion, ///< Transparent Union Conversions
- ICK_Writeback_Conversion, ///< Objective-C ARC writeback conversion
- ICK_Zero_Event_Conversion, ///< Zero constant to event (OpenCL1.2 6.12.10)
- ICK_Zero_Queue_Conversion, ///< Zero constant to queue
- ICK_C_Only_Conversion, ///< Conversions allowed in C, but not C++
- ICK_Incompatible_Pointer_Conversion, ///< C-only conversion between pointers
- /// with incompatible types
- ICK_Num_Conversion_Kinds, ///< The number of conversion kinds
+ /// Identity conversion (no conversion)
+ ICK_Identity = 0,
+
+ /// Lvalue-to-rvalue conversion (C++ [conv.lval])
+ ICK_Lvalue_To_Rvalue,
+
+ /// Array-to-pointer conversion (C++ [conv.array])
+ ICK_Array_To_Pointer,
+
+ /// Function-to-pointer (C++ [conv.array])
+ ICK_Function_To_Pointer,
+
+ /// Function pointer conversion (C++17 [conv.fctptr])
+ ICK_Function_Conversion,
+
+ /// Qualification conversions (C++ [conv.qual])
+ ICK_Qualification,
+
+ /// Integral promotions (C++ [conv.prom])
+ ICK_Integral_Promotion,
+
+ /// Floating point promotions (C++ [conv.fpprom])
+ ICK_Floating_Promotion,
+
+ /// Complex promotions (Clang extension)
+ ICK_Complex_Promotion,
+
+ /// Integral conversions (C++ [conv.integral])
+ ICK_Integral_Conversion,
+
+ /// Floating point conversions (C++ [conv.double]
+ ICK_Floating_Conversion,
+
+ /// Complex conversions (C99 6.3.1.6)
+ ICK_Complex_Conversion,
+
+ /// Floating-integral conversions (C++ [conv.fpint])
+ ICK_Floating_Integral,
+
+ /// Pointer conversions (C++ [conv.ptr])
+ ICK_Pointer_Conversion,
+
+ /// Pointer-to-member conversions (C++ [conv.mem])
+ ICK_Pointer_Member,
+
+ /// Boolean conversions (C++ [conv.bool])
+ ICK_Boolean_Conversion,
+
+ /// Conversions between compatible types in C99
+ ICK_Compatible_Conversion,
+
+ /// Derived-to-base (C++ [over.best.ics])
+ ICK_Derived_To_Base,
+
+ /// Vector conversions
+ ICK_Vector_Conversion,
+
+ /// A vector splat from an arithmetic type
+ ICK_Vector_Splat,
+
+ /// Complex-real conversions (C99 6.3.1.7)
+ ICK_Complex_Real,
+
+ /// Block Pointer conversions
+ ICK_Block_Pointer_Conversion,
+
+ /// Transparent Union Conversions
+ ICK_TransparentUnionConversion,
+
+ /// Objective-C ARC writeback conversion
+ ICK_Writeback_Conversion,
+
+ /// Zero constant to event (OpenCL1.2 6.12.10)
+ ICK_Zero_Event_Conversion,
+
+ /// Zero constant to queue
+ ICK_Zero_Queue_Conversion,
+
+ /// Conversions allowed in C, but not C++
+ ICK_C_Only_Conversion,
+
+ /// C-only conversion between pointers with incompatible types
+ ICK_Incompatible_Pointer_Conversion,
+
+ /// The number of conversion kinds
+ ICK_Num_Conversion_Kinds,
};
/// ImplicitConversionRank - The rank of an implicit conversion
@@ -95,16 +170,30 @@ namespace clang {
/// 13.3.3.1.1) and are listed such that better conversion ranks
/// have smaller values.
enum ImplicitConversionRank {
- ICR_Exact_Match = 0, ///< Exact Match
- ICR_Promotion, ///< Promotion
- ICR_Conversion, ///< Conversion
- ICR_OCL_Scalar_Widening, ///< OpenCL Scalar Widening
- ICR_Complex_Real_Conversion, ///< Complex <-> Real conversion
- ICR_Writeback_Conversion, ///< ObjC ARC writeback conversion
- ICR_C_Conversion, ///< Conversion only allowed in the C standard.
- /// (e.g. void* to char*)
- ICR_C_Conversion_Extension ///< Conversion not allowed by the C standard,
- /// but that we accept as an extension anyway.
+ /// Exact Match
+ ICR_Exact_Match = 0,
+
+ /// Promotion
+ ICR_Promotion,
+
+ /// Conversion
+ ICR_Conversion,
+
+ /// OpenCL Scalar Widening
+ ICR_OCL_Scalar_Widening,
+
+ /// Complex <-> Real conversion
+ ICR_Complex_Real_Conversion,
+
+ /// ObjC ARC writeback conversion
+ ICR_Writeback_Conversion,
+
+ /// Conversion only allowed in the C standard (e.g. void* to char*).
+ ICR_C_Conversion,
+
+ /// Conversion not allowed by the C standard, but that we accept as an
+ /// extension anyway.
+ ICR_C_Conversion_Extension
};
ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind);
@@ -155,12 +244,12 @@ namespace clang {
/// or a function conversion.
ImplicitConversionKind Third : 8;
- /// \brief Whether this is the deprecated conversion of a
+ /// Whether this is the deprecated conversion of a
/// string literal to a pointer to non-const character data
/// (C++ 4.2p2).
unsigned DeprecatedStringLiteralToCharPtr : 1;
- /// \brief Whether the qualification conversion involves a change in the
+ /// Whether the qualification conversion involves a change in the
/// Objective-C lifetime (for automatic reference counting).
unsigned QualificationIncludesObjCLifetime : 1;
@@ -176,21 +265,21 @@ namespace clang {
/// direct binding (C++ [dcl.init.ref]).
unsigned DirectBinding : 1;
- /// \brief Whether this is an lvalue reference binding (otherwise, it's
+ /// Whether this is an lvalue reference binding (otherwise, it's
/// an rvalue reference binding).
unsigned IsLvalueReference : 1;
- /// \brief Whether we're binding to a function lvalue.
+ /// Whether we're binding to a function lvalue.
unsigned BindsToFunctionLvalue : 1;
- /// \brief Whether we're binding to an rvalue.
+ /// Whether we're binding to an rvalue.
unsigned BindsToRvalue : 1;
- /// \brief Whether this binds an implicit object argument to a
+ /// Whether this binds an implicit object argument to a
/// non-static member function without a ref-qualifier.
unsigned BindsImplicitObjectArgumentWithoutRefQualifier : 1;
- /// \brief Whether this binds a reference to an object with a different
+ /// Whether this binds a reference to an object with a different
/// Objective-C lifetime qualifier.
unsigned ObjCLifetimeConversionBinding : 1;
@@ -213,10 +302,12 @@ namespace clang {
DeclAccessPair FoundCopyConstructor;
void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
+
void setToType(unsigned Idx, QualType T) {
assert(Idx < 3 && "To type index is out of range");
ToTypePtrs[Idx] = T.getAsOpaquePtr();
}
+
void setAllToTypes(QualType T) {
ToTypePtrs[0] = T.getAsOpaquePtr();
ToTypePtrs[1] = ToTypePtrs[0];
@@ -226,6 +317,7 @@ namespace clang {
QualType getFromType() const {
return QualType::getFromOpaquePtr(FromTypePtr);
}
+
QualType getToType(unsigned Idx) const {
assert(Idx < 3 && "To type index is out of range");
return QualType::getFromOpaquePtr(ToTypePtrs[Idx]);
@@ -238,9 +330,10 @@ namespace clang {
}
ImplicitConversionRank getRank() const;
- NarrowingKind getNarrowingKind(ASTContext &Context, const Expr *Converted,
- APValue &ConstantValue,
- QualType &ConstantType) const;
+ NarrowingKind
+ getNarrowingKind(ASTContext &Context, const Expr *Converted,
+ APValue &ConstantValue, QualType &ConstantType,
+ bool IgnoreFloatToIntegralConversion = false) const;
bool isPointerConversionToBool() const;
bool isPointerConversionToVoidPointer(ASTContext& Context) const;
void dump() const;
@@ -249,7 +342,7 @@ namespace clang {
/// UserDefinedConversionSequence - Represents a user-defined
/// conversion sequence (C++ 13.3.3.1.2).
struct UserDefinedConversionSequence {
- /// \brief Represents the standard conversion that occurs before
+ /// Represents the standard conversion that occurs before
/// the actual user-defined conversion.
///
/// C++11 13.3.3.1.2p1:
@@ -284,7 +377,7 @@ namespace clang {
/// aggregate initialization from an initializer list.
FunctionDecl* ConversionFunction;
- /// \brief The declaration that we found via name lookup, which might be
+ /// The declaration that we found via name lookup, which might be
/// the same as \c ConversionFunction or it might be a using declaration
/// that refers to \c ConversionFunction.
DeclAccessPair FoundConversionFunction;
@@ -294,7 +387,8 @@ namespace clang {
/// Represents an ambiguous user-defined conversion sequence.
struct AmbiguousConversionSequence {
- typedef SmallVector<std::pair<NamedDecl*, FunctionDecl*>, 4> ConversionSet;
+ using ConversionSet =
+ SmallVector<std::pair<NamedDecl *, FunctionDecl *>, 4>;
void *FromTypePtr;
void *ToTypePtr;
@@ -303,9 +397,11 @@ namespace clang {
QualType getFromType() const {
return QualType::getFromOpaquePtr(FromTypePtr);
}
+
QualType getToType() const {
return QualType::getFromOpaquePtr(ToTypePtr);
}
+
void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); }
@@ -321,11 +417,13 @@ namespace clang {
conversions().push_back(std::make_pair(Found, D));
}
- typedef ConversionSet::iterator iterator;
+ using iterator = ConversionSet::iterator;
+
iterator begin() { return conversions().begin(); }
iterator end() { return conversions().end(); }
- typedef ConversionSet::const_iterator const_iterator;
+ using const_iterator = ConversionSet::const_iterator;
+
const_iterator begin() const { return conversions().begin(); }
const_iterator end() const { return conversions().end(); }
@@ -362,6 +460,7 @@ namespace clang {
init(K, From->getType(), To);
FromExpr = From;
}
+
void init(FailureKind K, QualType From, QualType To) {
Kind = K;
FromExpr = nullptr;
@@ -376,6 +475,7 @@ namespace clang {
FromExpr = E;
setFromType(E->getType());
}
+
void setFromType(QualType T) { FromTy = T.getAsOpaquePtr(); }
void setToType(QualType T) { ToTy = T.getAsOpaquePtr(); }
};
@@ -406,7 +506,7 @@ namespace clang {
/// ConversionKind - The kind of implicit conversion sequence.
unsigned ConversionKind : 30;
- /// \brief Whether the target is really a std::initializer_list, and the
+ /// Whether the target is really a std::initializer_list, and the
/// sequence only represents the worst element conversion.
unsigned StdInitializerListElement : 1;
@@ -442,13 +542,10 @@ namespace clang {
: ConversionKind(Uninitialized), StdInitializerListElement(false) {
Standard.setAsIdentityConversion();
}
- ~ImplicitConversionSequence() {
- destruct();
- }
+
ImplicitConversionSequence(const ImplicitConversionSequence &Other)
- : ConversionKind(Other.ConversionKind),
- StdInitializerListElement(Other.StdInitializerListElement)
- {
+ : ConversionKind(Other.ConversionKind),
+ StdInitializerListElement(Other.StdInitializerListElement) {
switch (ConversionKind) {
case Uninitialized: break;
case StandardConversion: Standard = Other.Standard; break;
@@ -460,18 +557,22 @@ namespace clang {
}
ImplicitConversionSequence &
- operator=(const ImplicitConversionSequence &Other) {
+ operator=(const ImplicitConversionSequence &Other) {
destruct();
new (this) ImplicitConversionSequence(Other);
return *this;
}
+ ~ImplicitConversionSequence() {
+ destruct();
+ }
+
Kind getKind() const {
assert(isInitialized() && "querying uninitialized conversion");
return Kind(ConversionKind);
}
- /// \brief Return a ranking of the implicit conversion sequence
+ /// Return a ranking of the implicit conversion sequence
/// kind, where smaller ranks represent better conversion
/// sequences.
///
@@ -526,6 +627,7 @@ namespace clang {
void setStandard() { setKind(StandardConversion); }
void setEllipsis() { setKind(EllipsisConversion); }
void setUserDefined() { setKind(UserDefinedConversion); }
+
void setAmbiguous() {
if (ConversionKind == AmbiguousConversion) return;
ConversionKind = AmbiguousConversion;
@@ -539,7 +641,7 @@ namespace clang {
Standard.setAllToTypes(T);
}
- /// \brief Whether the target is really a std::initializer_list, and the
+ /// Whether the target is really a std::initializer_list, and the
/// sequence only represents the worst element conversion.
bool isStdInitializerListElement() const {
return StdInitializerListElement;
@@ -613,12 +715,16 @@ namespace clang {
/// This inherited constructor is not viable because it would slice the
/// argument.
ovl_fail_inhctor_slice,
+
+ /// This candidate was not viable because it is a non-default multiversioned
+ /// function.
+ ovl_non_default_multiversion_function,
};
/// A list of implicit conversion sequences for the arguments of an
/// OverloadCandidate.
- typedef llvm::MutableArrayRef<ImplicitConversionSequence>
- ConversionSequenceList;
+ using ConversionSequenceList =
+ llvm::MutableArrayRef<ImplicitConversionSequence>;
/// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
struct OverloadCandidate {
@@ -669,7 +775,7 @@ namespace clang {
/// Actually an OverloadFailureKind.
unsigned char FailureKind;
- /// \brief The number of call arguments that were explicitly provided,
+ /// The number of call arguments that were explicitly provided,
/// to be used while performing partial ordering of function templates.
unsigned ExplicitCallArguments;
@@ -726,16 +832,19 @@ namespace clang {
enum CandidateSetKind {
/// Normal lookup.
CSK_Normal,
+
/// C++ [over.match.oper]:
/// Lookup of operator function candidates in a call using operator
/// syntax. Candidates that have no parameters of class type will be
/// skipped unless there is a parameter of (reference to) enum type and
/// the corresponding argument is of the same enum type.
CSK_Operator,
+
/// C++ [over.match.copy]:
/// Copy-initialization of an object of class type by user-defined
/// conversion.
CSK_InitByUserDefinedConversion,
+
/// C++ [over.match.ctor], [over.match.list]
/// Initialization of an object of class type by constructor,
/// using either a parenthesized or braced list of arguments.
@@ -755,7 +864,7 @@ namespace clang {
constexpr static unsigned NumInlineBytes =
24 * sizeof(ImplicitConversionSequence);
- unsigned NumInlineBytesUsed;
+ unsigned NumInlineBytesUsed = 0;
llvm::AlignedCharArray<alignof(void *), NumInlineBytes> InlineSpace;
/// If we have space, allocates from inline storage. Otherwise, allocates
@@ -784,36 +893,36 @@ namespace clang {
return reinterpret_cast<T *>(FreeSpaceStart);
}
- OverloadCandidateSet(const OverloadCandidateSet &) = delete;
- void operator=(const OverloadCandidateSet &) = delete;
-
void destroyCandidates();
public:
OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK)
- : Loc(Loc), Kind(CSK), NumInlineBytesUsed(0) {}
+ : Loc(Loc), Kind(CSK) {}
+ OverloadCandidateSet(const OverloadCandidateSet &) = delete;
+ OverloadCandidateSet &operator=(const OverloadCandidateSet &) = delete;
~OverloadCandidateSet() { destroyCandidates(); }
SourceLocation getLocation() const { return Loc; }
CandidateSetKind getKind() const { return Kind; }
- /// \brief Determine when this overload candidate will be new to the
+ /// Determine when this overload candidate will be new to the
/// overload set.
bool isNewCandidate(Decl *F) {
return Functions.insert(F->getCanonicalDecl()).second;
}
- /// \brief Clear out all of the candidates.
+ /// Clear out all of the candidates.
void clear(CandidateSetKind CSK);
- typedef SmallVectorImpl<OverloadCandidate>::iterator iterator;
+ using iterator = SmallVectorImpl<OverloadCandidate>::iterator;
+
iterator begin() { return Candidates.begin(); }
iterator end() { return Candidates.end(); }
size_t size() const { return Candidates.size(); }
bool empty() const { return Candidates.empty(); }
- /// \brief Allocate storage for conversion sequences for NumConversions
+ /// Allocate storage for conversion sequences for NumConversions
/// conversions.
ConversionSequenceList
allocateConversionSequences(unsigned NumConversions) {
@@ -827,7 +936,7 @@ namespace clang {
return ConversionSequenceList(Conversions, NumConversions);
}
- /// \brief Add a new candidate with NumConversions conversion sequence slots
+ /// Add a new candidate with NumConversions conversion sequence slots
/// to the overload set.
OverloadCandidate &addCandidate(unsigned NumConversions = 0,
ConversionSequenceList Conversions = None) {
@@ -865,8 +974,10 @@ namespace clang {
DeclAccessPair FoundDecl;
CXXConstructorDecl *Constructor;
FunctionTemplateDecl *ConstructorTmpl;
+
explicit operator bool() const { return Constructor; }
};
+
// FIXME: Add an AddOverloadCandidate / AddTemplateOverloadCandidate overload
// that takes one of these.
inline ConstructorInfo getConstructorInfo(NamedDecl *ND) {
@@ -884,6 +995,7 @@ namespace clang {
Info.Constructor = dyn_cast<CXXConstructorDecl>(D);
return Info;
}
-} // end namespace clang
+
+} // namespace clang
#endif // LLVM_CLANG_SEMA_OVERLOAD_H
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
index 1e35316fd5dd5..ae2f178df1ec9 100644
--- a/include/clang/Sema/Ownership.h
+++ b/include/clang/Sema/Ownership.h
@@ -1,4 +1,4 @@
-//===--- Ownership.h - Parser ownership helpers -----------------*- C++ -*-===//
+//===- Ownership.h - Parser ownership helpers -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,23 +17,29 @@
#include "clang/AST/Expr.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/type_traits.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
//===----------------------------------------------------------------------===//
// OpaquePtr
//===----------------------------------------------------------------------===//
namespace clang {
- class CXXCtorInitializer;
- class CXXBaseSpecifier;
- class Decl;
- class Expr;
- class ParsedTemplateArgument;
- class QualType;
- class Stmt;
- class TemplateName;
- class TemplateParameterList;
-
- /// \brief Wrapper for void* pointer.
+
+class CXXBaseSpecifier;
+class CXXCtorInitializer;
+class Decl;
+class Expr;
+class ParsedTemplateArgument;
+class QualType;
+class Stmt;
+class TemplateName;
+class TemplateParameterList;
+
+ /// Wrapper for void* pointer.
/// \tparam PtrTy Either a pointer type like 'T*' or a type that behaves like
/// a pointer.
///
@@ -44,16 +50,17 @@ namespace clang {
template <class PtrTy>
class OpaquePtr {
void *Ptr = nullptr;
+
explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {}
- typedef llvm::PointerLikeTypeTraits<PtrTy> Traits;
+ using Traits = llvm::PointerLikeTypeTraits<PtrTy>;
public:
OpaquePtr(std::nullptr_t = nullptr) {}
static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; }
- /// \brief Returns plain pointer to the entity pointed by this wrapper.
+ /// Returns plain pointer to the entity pointed by this wrapper.
/// \tparam PointeeT Type of pointed entity.
///
/// It is identical to getPtrAs<PointeeT*>.
@@ -61,7 +68,7 @@ namespace clang {
return get();
}
- /// \brief Returns pointer converted to the specified type.
+ /// Returns pointer converted to the specified type.
/// \tparam PtrT Result pointer type. There must be implicit conversion
/// from PtrTy to PtrT.
///
@@ -103,26 +110,32 @@ namespace clang {
return *this;
}
};
-}
+
+} // namespace clang
namespace llvm {
+
template <class T>
- struct PointerLikeTypeTraits<clang::OpaquePtr<T> > {
+ struct PointerLikeTypeTraits<clang::OpaquePtr<T>> {
+ enum { NumLowBitsAvailable = 0 };
+
static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) {
// FIXME: Doesn't work? return P.getAs< void >();
return P.getAsOpaquePtr();
}
+
static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) {
return clang::OpaquePtr<T>::getFromOpaquePtr(P);
}
- enum { NumLowBitsAvailable = 0 };
};
template <class T>
- struct isPodLike<clang::OpaquePtr<T> > { static const bool value = true; };
-}
+ struct isPodLike<clang::OpaquePtr<T>> { static const bool value = true; };
+
+} // namespace llvm
namespace clang {
+
// Basic
class DiagnosticBuilder;
@@ -146,8 +159,7 @@ namespace clang {
bool Invalid;
public:
- ActionResult(bool Invalid = false)
- : Val(PtrTy()), Invalid(Invalid) {}
+ ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {}
ActionResult(PtrTy val) : Val(val), Invalid(false) {}
ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {}
@@ -178,17 +190,20 @@ namespace clang {
// A pointer whose low bit is 1 if this result is invalid, 0
// otherwise.
uintptr_t PtrWithInvalid;
- typedef llvm::PointerLikeTypeTraits<PtrTy> PtrTraits;
+
+ using PtrTraits = llvm::PointerLikeTypeTraits<PtrTy>;
+
public:
ActionResult(bool Invalid = false)
- : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) { }
+ : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) {}
ActionResult(PtrTy V) {
void *VP = PtrTraits::getAsVoidPointer(V);
PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
}
- ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) { }
+
+ ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) {}
// These two overloads prevent void* -> bool conversions.
ActionResult(const void *) = delete;
@@ -202,6 +217,7 @@ namespace clang {
void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01);
return PtrTraits::getFromVoidPointer(VP);
}
+
template <typename T> T *getAs() { return static_cast<T*>(get()); }
void set(PtrTy V) {
@@ -229,8 +245,8 @@ namespace clang {
/// An opaque type for threading parsed type information through the
/// parser.
- typedef OpaquePtr<QualType> ParsedType;
- typedef UnionOpaquePtr<QualType> UnionParsedType;
+ using ParsedType = OpaquePtr<QualType>;
+ using UnionParsedType = UnionOpaquePtr<QualType>;
// We can re-use the low bit of expression, statement, base, and
// member-initializer pointers for the "invalid" flag of
@@ -248,21 +264,21 @@ namespace clang {
static const bool value = true;
};
- typedef ActionResult<Expr*> ExprResult;
- typedef ActionResult<Stmt*> StmtResult;
- typedef ActionResult<ParsedType> TypeResult;
- typedef ActionResult<CXXBaseSpecifier*> BaseResult;
- typedef ActionResult<CXXCtorInitializer*> MemInitResult;
+ using ExprResult = ActionResult<Expr *>;
+ using StmtResult = ActionResult<Stmt *>;
+ using TypeResult = ActionResult<ParsedType>;
+ using BaseResult = ActionResult<CXXBaseSpecifier *>;
+ using MemInitResult = ActionResult<CXXCtorInitializer *>;
- typedef ActionResult<Decl*> DeclResult;
- typedef OpaquePtr<TemplateName> ParsedTemplateTy;
- typedef UnionOpaquePtr<TemplateName> UnionParsedTemplateTy;
+ using DeclResult = ActionResult<Decl *>;
+ using ParsedTemplateTy = OpaquePtr<TemplateName>;
+ using UnionParsedTemplateTy = UnionOpaquePtr<TemplateName>;
- typedef MutableArrayRef<Expr*> MultiExprArg;
- typedef MutableArrayRef<Stmt*> MultiStmtArg;
- typedef MutableArrayRef<ParsedTemplateArgument> ASTTemplateArgsPtr;
- typedef MutableArrayRef<ParsedType> MultiTypeArg;
- typedef MutableArrayRef<TemplateParameterList*> MultiTemplateParamsArg;
+ using MultiExprArg = MutableArrayRef<Expr *>;
+ using MultiStmtArg = MutableArrayRef<Stmt *>;
+ using ASTTemplateArgsPtr = MutableArrayRef<ParsedTemplateArgument>;
+ using MultiTypeArg = MutableArrayRef<ParsedType>;
+ using MultiTemplateParamsArg = MutableArrayRef<TemplateParameterList *>;
inline ExprResult ExprError() { return ExprResult(true); }
inline StmtResult StmtError() { return StmtResult(true); }
@@ -282,6 +298,7 @@ namespace clang {
assert(!R.isInvalid() && "operation was asserted to never fail!");
return R.get();
}
-}
-#endif
+} // namespace clang
+
+#endif // LLVM_CLANG_SEMA_OWNERSHIP_H
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/ParsedAttr.h
index 4e806116c4d9b..3f293247787ca 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/ParsedAttr.h
@@ -1,4 +1,4 @@
-//===--- AttributeList.h - Parsed attribute sets ----------------*- C++ -*-===//
+//======- ParsedAttr.h - Parsed attribute sets ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the AttributeList class, which is used to collect
+// This file defines the ParsedAttr class, which is used to collect
// parsed attributes.
//
//===----------------------------------------------------------------------===//
@@ -18,45 +18,54 @@
#include "clang/Basic/AttrSubjectMatchRules.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/VersionTuple.h"
#include "clang/Sema/Ownership.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/VersionTuple.h"
#include <cassert>
+#include <cstddef>
+#include <cstring>
+#include <utility>
namespace clang {
- class ASTContext;
- class IdentifierInfo;
- class Expr;
-/// \brief Represents information about a change in availability for
+class ASTContext;
+class Decl;
+class Expr;
+class IdentifierInfo;
+class LangOptions;
+
+/// Represents information about a change in availability for
/// an entity, which is part of the encoding of the 'availability'
/// attribute.
struct AvailabilityChange {
- /// \brief The location of the keyword indicating the kind of change.
+ /// The location of the keyword indicating the kind of change.
SourceLocation KeywordLoc;
- /// \brief The version number at which the change occurred.
+ /// The version number at which the change occurred.
VersionTuple Version;
- /// \brief The source range covering the version number.
+ /// The source range covering the version number.
SourceRange VersionRange;
- /// \brief Determine whether this availability change is valid.
+ /// Determine whether this availability change is valid.
bool isValid() const { return !Version.empty(); }
};
namespace {
+
enum AvailabilitySlot {
IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
};
-/// Describes the trailing object for Availability attribute in AttributeList.
+/// Describes the trailing object for Availability attribute in ParsedAttr.
struct AvailabilityData {
AvailabilityChange Changes[NumAvailabilitySlots];
SourceLocation StrictLoc;
const Expr *Replacement;
+
AvailabilityData(const AvailabilityChange &Introduced,
const AvailabilityChange &Deprecated,
const AvailabilityChange &Obsoleted,
@@ -67,9 +76,10 @@ struct AvailabilityData {
Changes[ObsoletedSlot] = Obsoleted;
}
};
-}
-/// \brief Wraps an identifier and optional source location for the identifier.
+} // namespace
+
+/// Wraps an identifier and optional source location for the identifier.
struct IdentifierLoc {
SourceLocation Loc;
IdentifierInfo *Ident;
@@ -78,12 +88,12 @@ struct IdentifierLoc {
IdentifierInfo *Ident);
};
-/// \brief A union of the various pointer types that can be passed to an
-/// AttributeList as an argument.
-typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion;
-typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector;
+/// A union of the various pointer types that can be passed to an
+/// ParsedAttr as an argument.
+using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
+using ArgsVector = llvm::SmallVector<ArgsUnion, 12U>;
-/// AttributeList - Represents a syntactic attribute.
+/// ParsedAttr - Represents a syntactic attribute.
///
/// For a GNU attribute, there are four forms of this construct:
///
@@ -92,24 +102,31 @@ typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector;
/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
///
-class AttributeList { // TODO: This should really be called ParsedAttribute
+class ParsedAttr { // TODO: This should really be called ParsedAttribute
public:
/// The style used to specify an attribute.
enum Syntax {
/// __attribute__((...))
AS_GNU,
+
/// [[...]]
AS_CXX11,
+
/// [[...]]
AS_C2x,
+
/// __declspec(...)
AS_Declspec,
+
/// [uuid("...")] class Foo
AS_Microsoft,
+
/// __ptr16, alignas(...), etc.
AS_Keyword,
+
/// #pragma ...
AS_Pragma,
+
// Note TableGen depends on the order above. Do not add or change the order
// without adding related code to TableGen/ClangAttrEmitter.cpp.
/// Context-sensitive version of a keyword attribute.
@@ -159,18 +176,12 @@ private:
/// A cached value.
mutable unsigned ProcessingCache : 8;
- /// \brief The location of the 'unavailable' keyword in an
+ /// The location of the 'unavailable' keyword in an
/// availability attribute.
SourceLocation UnavailableLoc;
const Expr *MessageExpr;
- /// The next attribute in the current position.
- AttributeList *NextInPosition;
-
- /// The next attribute allocated in the current Pool.
- AttributeList *NextInPool;
-
/// Arguments, if any, are stored immediately following the object.
ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); }
ArgsUnion const *getArgsBuffer() const {
@@ -194,83 +205,43 @@ public:
};
struct PropertyData {
IdentifierInfo *GetterId, *SetterId;
+
PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
- : GetterId(getterId), SetterId(setterId) {}
+ : GetterId(getterId), SetterId(setterId) {}
};
private:
- /// Type tag information is stored immediately following the arguments, if
- /// any, at the end of the object. They are mutually exlusive with
- /// availability slots.
- TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
- return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
- }
-
- const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
- return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
- + NumArgs);
- }
-
- /// The type buffer immediately follows the object and are mutually exclusive
- /// with arguments.
- ParsedType &getTypeBuffer() {
- return *reinterpret_cast<ParsedType *>(this + 1);
- }
-
- const ParsedType &getTypeBuffer() const {
- return *reinterpret_cast<const ParsedType *>(this + 1);
- }
-
- /// The property data immediately follows the object is is mutually exclusive
- /// with arguments.
- PropertyData &getPropertyDataBuffer() {
- assert(IsProperty);
- return *reinterpret_cast<PropertyData*>(this + 1);
- }
-
- const PropertyData &getPropertyDataBuffer() const {
- assert(IsProperty);
- return *reinterpret_cast<const PropertyData*>(this + 1);
- }
-
- AttributeList(const AttributeList &) = delete;
- void operator=(const AttributeList &) = delete;
- void operator delete(void *) = delete;
- ~AttributeList() = delete;
-
- size_t allocated_size() const;
+ friend class AttributeFactory;
+ friend class AttributePool;
/// Constructor for attributes with expression arguments.
- AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ArgsUnion *args, unsigned numArgs,
- Syntax syntaxUsed, SourceLocation ellipsisLoc)
- : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
- ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
- SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
- IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
- HasParsedType(false), HasProcessingCache(false),
- NextInPosition(nullptr), NextInPool(nullptr) {
+ ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed,
+ SourceLocation ellipsisLoc)
+ : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+ ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
+ SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
+ IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
+ HasParsedType(false), HasProcessingCache(false) {
if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
/// Constructor for availability attributes.
- AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Parm, const AvailabilityChange &introduced,
- const AvailabilityChange &deprecated,
- const AvailabilityChange &obsoleted,
- SourceLocation unavailable,
- const Expr *messageExpr,
- Syntax syntaxUsed, SourceLocation strict,
- const Expr *replacementExpr)
- : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
- ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
- Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
- IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
- HasProcessingCache(false), UnavailableLoc(unavailable),
- MessageExpr(messageExpr), NextInPosition(nullptr), NextInPool(nullptr) {
+ ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *Parm, const AvailabilityChange &introduced,
+ const AvailabilityChange &deprecated,
+ const AvailabilityChange &obsoleted, SourceLocation unavailable,
+ const Expr *messageExpr, Syntax syntaxUsed, SourceLocation strict,
+ const Expr *replacementExpr)
+ : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+ ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
+ UsedAsTypeAttr(false), IsAvailability(true),
+ IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
+ HasProcessingCache(false), UnavailableLoc(unavailable),
+ MessageExpr(messageExpr) {
ArgsUnion PVal(Parm);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
new (getAvailabilityData()) AvailabilityData(
@@ -279,17 +250,15 @@ private:
}
/// Constructor for objc_bridge_related attributes.
- AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Parm1,
- IdentifierLoc *Parm2,
- IdentifierLoc *Parm3,
- Syntax syntaxUsed)
- : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
- ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
- Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
- IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
- HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
+ ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *Parm1, IdentifierLoc *Parm2, IdentifierLoc *Parm3,
+ Syntax syntaxUsed)
+ : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+ ScopeLoc(scopeLoc), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(false),
+ UsedAsTypeAttr(false), IsAvailability(false),
+ IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
+ HasProcessingCache(false) {
ArgsUnion *Args = getArgsBuffer();
Args[0] = Parm1;
Args[1] = Parm2;
@@ -298,15 +267,15 @@ private:
}
/// Constructor for type_tag_for_datatype attribute.
- AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *ArgKind, ParsedType matchingCType,
- bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
- : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
- ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
- Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
- IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
- HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
+ ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *ArgKind, ParsedType matchingCType,
+ bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
+ : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+ ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
+ UsedAsTypeAttr(false), IsAvailability(false),
+ IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
+ HasProcessingCache(false) {
ArgsUnion PVal(ArgKind);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
@@ -317,36 +286,72 @@ private:
}
/// Constructor for attributes with a single type argument.
- AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ParsedType typeArg, Syntax syntaxUsed)
+ ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ ParsedType typeArg, Syntax syntaxUsed)
: AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
- ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
- Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
+ ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false),
+ UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
- HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr){
+ HasProcessingCache(false) {
new (&getTypeBuffer()) ParsedType(typeArg);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
/// Constructor for microsoft __declspec(property) attribute.
- AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierInfo *getterId, IdentifierInfo *setterId,
- Syntax syntaxUsed)
- : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
- ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
- Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
- IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
- HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
+ ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *getterId, IdentifierInfo *setterId,
+ Syntax syntaxUsed)
+ : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+ ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false),
+ UsedAsTypeAttr(false), IsAvailability(false),
+ IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
+ HasProcessingCache(false) {
new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
- friend class AttributePool;
- friend class AttributeFactory;
+ /// Type tag information is stored immediately following the arguments, if
+ /// any, at the end of the object. They are mutually exclusive with
+ /// availability slots.
+ TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
+ return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
+ }
+ const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
+ return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
+ + NumArgs);
+ }
+
+ /// The type buffer immediately follows the object and are mutually exclusive
+ /// with arguments.
+ ParsedType &getTypeBuffer() {
+ return *reinterpret_cast<ParsedType *>(this + 1);
+ }
+ const ParsedType &getTypeBuffer() const {
+ return *reinterpret_cast<const ParsedType *>(this + 1);
+ }
+
+ /// The property data immediately follows the object is is mutually exclusive
+ /// with arguments.
+ PropertyData &getPropertyDataBuffer() {
+ assert(IsProperty);
+ return *reinterpret_cast<PropertyData*>(this + 1);
+ }
+ const PropertyData &getPropertyDataBuffer() const {
+ assert(IsProperty);
+ return *reinterpret_cast<const PropertyData*>(this + 1);
+ }
+
+ size_t allocated_size() const;
public:
+ ParsedAttr(const ParsedAttr &) = delete;
+ ParsedAttr &operator=(const ParsedAttr &) = delete;
+ ~ParsedAttr() = delete;
+
+ void operator delete(void *) = delete;
+
enum Kind {
#define PARSED_ATTR(NAME) AT_##NAME,
#include "clang/Sema/AttrParsedAttrList.inc"
@@ -377,12 +382,15 @@ public:
bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
+
bool isCXX11Attribute() const {
return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
}
+
bool isC2xAttribute() const {
return SyntaxUsed == AS_C2x;
}
+
bool isKeywordAttribute() const {
return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
}
@@ -395,10 +403,12 @@ public:
void setInvalid(bool b = true) const { Invalid = b; }
bool hasProcessingCache() const { return HasProcessingCache; }
+
unsigned getProcessingCache() const {
assert(hasProcessingCache());
return ProcessingCache;
}
+
void setProcessingCache(unsigned value) const {
ProcessingCache = value;
HasProcessingCache = true;
@@ -414,9 +424,6 @@ public:
static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
Syntax SyntaxUsed);
- AttributeList *getNext() const { return NextInPosition; }
- void setNext(AttributeList *N) { NextInPosition = N; }
-
/// getNumArgs - Return the number of actual arguments to this attribute.
unsigned getNumArgs() const { return NumArgs; }
@@ -429,6 +436,7 @@ public:
bool isArgExpr(unsigned Arg) const {
return Arg < NumArgs && getArg(Arg).is<Expr*>();
}
+
Expr *getArgAsExpr(unsigned Arg) const {
return getArg(Arg).get<Expr*>();
}
@@ -436,6 +444,7 @@ public:
bool isArgIdent(unsigned Arg) const {
return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
}
+
IdentifierLoc *getArgAsIdent(unsigned Arg) const {
return getArg(Arg).get<IdentifierLoc*>();
}
@@ -503,7 +512,7 @@ public:
return getPropertyDataBuffer();
}
- /// \brief Get an index into the attribute spelling list
+ /// Get an index into the attribute spelling list
/// defined in Attr.td. This index is used by an attribute
/// to pretty print itself.
unsigned getAttributeSpellingListIndex() const;
@@ -526,7 +535,7 @@ public:
bool isKnownToGCC() const;
bool isSupportedByPragmaAttribute() const;
- /// \brief If the parsed attribute has a semantic equivalent, and it would
+ /// If the parsed attribute has a semantic equivalent, and it would
/// have a semantic Spelling enumeration (due to having semantically-distinct
/// spelling variations), return the value of that semantic spelling. If the
/// parsed attribute does not have a semantic equivalent, or would not have
@@ -534,6 +543,7 @@ public:
unsigned getSemanticSpelling() const;
};
+class AttributePool;
/// A factory, from which one makes pools, from which one creates
/// individual attributes which are deallocated with the pool.
///
@@ -545,18 +555,17 @@ public:
/// The required allocation size of an availability attribute,
/// which we want to ensure is a multiple of sizeof(void*).
AvailabilityAllocSize =
- sizeof(AttributeList)
- + ((sizeof(AvailabilityData) + sizeof(void*) + sizeof(ArgsUnion) - 1)
- / sizeof(void*) * sizeof(void*)),
- TypeTagForDatatypeAllocSize =
- sizeof(AttributeList)
- + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
- sizeof(ArgsUnion) - 1)
- / sizeof(void*) * sizeof(void*),
+ sizeof(ParsedAttr) +
+ ((sizeof(AvailabilityData) + sizeof(void *) + sizeof(ArgsUnion) - 1) /
+ sizeof(void *) * sizeof(void *)),
+ TypeTagForDatatypeAllocSize = sizeof(ParsedAttr) +
+ (sizeof(ParsedAttr::TypeTagForDatatypeData) +
+ sizeof(void *) + sizeof(ArgsUnion) - 1) /
+ sizeof(void *) * sizeof(void *),
PropertyAllocSize =
- sizeof(AttributeList)
- + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
- / sizeof(void*) * sizeof(void*)
+ sizeof(ParsedAttr) +
+ (sizeof(ParsedAttr::PropertyData) + sizeof(void *) - 1) /
+ sizeof(void *) * sizeof(void *)
};
private:
@@ -567,14 +576,14 @@ private:
/// attribute that needs more than that; on x86-64 you'd need 10
/// expression arguments, and on i386 you'd need 19.
InlineFreeListsCapacity =
- 1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
+ 1 + (AvailabilityAllocSize - sizeof(ParsedAttr)) / sizeof(void *)
};
llvm::BumpPtrAllocator Alloc;
/// Free lists. The index is determined by the following formula:
- /// (size - sizeof(AttributeList)) / sizeof(void*)
- SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
+ /// (size - sizeof(ParsedAttr)) / sizeof(void*)
+ SmallVector<SmallVector<ParsedAttr *, 8>, InlineFreeListsCapacity> FreeLists;
// The following are the private interface used by AttributePool.
friend class AttributePool;
@@ -582,12 +591,14 @@ private:
/// Allocate an attribute of the given size.
void *allocate(size_t size);
+ void deallocate(ParsedAttr *AL);
+
/// Reclaim all the attributes in the given pool chain, which is
/// non-empty. Note that the current implementation is safe
/// against reclaiming things which were not actually allocated
/// with the allocator, although of course it's important to make
/// sure that their allocator lives at least as long as this one.
- void reclaimPool(AttributeList *head);
+ void reclaimPool(AttributePool &head);
public:
AttributeFactory();
@@ -595,294 +606,297 @@ public:
};
class AttributePool {
+ friend class AttributeFactory;
AttributeFactory &Factory;
- AttributeList *Head;
+ llvm::TinyPtrVector<ParsedAttr *> Attrs;
void *allocate(size_t size) {
return Factory.allocate(size);
}
- AttributeList *add(AttributeList *attr) {
- // We don't care about the order of the pool.
- attr->NextInPool = Head;
- Head = attr;
+ ParsedAttr *add(ParsedAttr *attr) {
+ Attrs.push_back(attr);
return attr;
}
- void takePool(AttributeList *pool);
+ void remove(ParsedAttr *attr) {
+ assert(llvm::is_contained(Attrs, attr) &&
+ "Can't take attribute from a pool that doesn't own it!");
+ Attrs.erase(llvm::find(Attrs, attr));
+ }
+
+ void takePool(AttributePool &pool);
public:
/// Create a new pool for a factory.
- AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
+ AttributePool(AttributeFactory &factory) : Factory(factory) {}
AttributePool(const AttributePool &) = delete;
+ ~AttributePool() { Factory.reclaimPool(*this); }
+
/// Move the given pool's allocations to this pool.
- AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) {
- pool.Head = nullptr;
- }
+ AttributePool(AttributePool &&pool) = default;
AttributeFactory &getFactory() const { return Factory; }
void clear() {
- if (Head) {
- Factory.reclaimPool(Head);
- Head = nullptr;
- }
+ Factory.reclaimPool(*this);
+ Attrs.clear();
}
/// Take the given pool's allocations and add them to this pool.
void takeAllFrom(AttributePool &pool) {
- if (pool.Head) {
- takePool(pool.Head);
- pool.Head = nullptr;
- }
- }
-
- ~AttributePool() {
- if (Head) Factory.reclaimPool(Head);
- }
-
- AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ArgsUnion *args, unsigned numArgs,
- AttributeList::Syntax syntax,
- SourceLocation ellipsisLoc = SourceLocation()) {
- void *memory = allocate(sizeof(AttributeList)
- + numArgs * sizeof(ArgsUnion));
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- args, numArgs, syntax,
- ellipsisLoc));
- }
-
- AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Param,
- const AvailabilityChange &introduced,
- const AvailabilityChange &deprecated,
- const AvailabilityChange &obsoleted,
- SourceLocation unavailable,
- const Expr *MessageExpr,
- AttributeList::Syntax syntax,
- SourceLocation strict, const Expr *ReplacementExpr) {
+ takePool(pool);
+ pool.Attrs.clear();
+ }
+
+ ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ ArgsUnion *args, unsigned numArgs,
+ ParsedAttr::Syntax syntax,
+ SourceLocation ellipsisLoc = SourceLocation()) {
+ void *memory = allocate(sizeof(ParsedAttr) + numArgs * sizeof(ArgsUnion));
+ return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
+ args, numArgs, syntax, ellipsisLoc));
+ }
+
+ ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *Param, const AvailabilityChange &introduced,
+ const AvailabilityChange &deprecated,
+ const AvailabilityChange &obsoleted,
+ SourceLocation unavailable, const Expr *MessageExpr,
+ ParsedAttr::Syntax syntax, SourceLocation strict,
+ const Expr *ReplacementExpr) {
void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- Param, introduced, deprecated,
- obsoleted, unavailable, MessageExpr,
- syntax, strict, ReplacementExpr));
- }
-
- AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Param1,
- IdentifierLoc *Param2,
- IdentifierLoc *Param3,
- AttributeList::Syntax syntax) {
- size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
+ return add(new (memory) ParsedAttr(
+ attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
+ obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
+ }
+
+ ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *Param1, IdentifierLoc *Param2,
+ IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
+ size_t size = sizeof(ParsedAttr) + 3 * sizeof(ArgsUnion);
void *memory = allocate(size);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- Param1, Param2, Param3,
- syntax));
- }
-
- AttributeList *createTypeTagForDatatype(
- IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *argumentKind, ParsedType matchingCType,
- bool layoutCompatible, bool mustBeNull,
- AttributeList::Syntax syntax) {
+ return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
+ Param1, Param2, Param3, syntax));
+ }
+
+ ParsedAttr *
+ createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *argumentKind,
+ ParsedType matchingCType, bool layoutCompatible,
+ bool mustBeNull, ParsedAttr::Syntax syntax) {
void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- argumentKind, matchingCType,
- layoutCompatible, mustBeNull,
- syntax));
- }
-
- AttributeList *createTypeAttribute(
- IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
- void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- typeArg, syntaxUsed));
- }
-
- AttributeList *createPropertyAttribute(
- IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierInfo *getterId, IdentifierInfo *setterId,
- AttributeList::Syntax syntaxUsed) {
+ return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
+ argumentKind, matchingCType,
+ layoutCompatible, mustBeNull, syntax));
+ }
+
+ ParsedAttr *createTypeAttribute(IdentifierInfo *attrName,
+ SourceRange attrRange,
+ IdentifierInfo *scopeName,
+ SourceLocation scopeLoc, ParsedType typeArg,
+ ParsedAttr::Syntax syntaxUsed) {
+ void *memory = allocate(sizeof(ParsedAttr) + sizeof(void *));
+ return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
+ typeArg, syntaxUsed));
+ }
+
+ ParsedAttr *
+ createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *getterId, IdentifierInfo *setterId,
+ ParsedAttr::Syntax syntaxUsed) {
void *memory = allocate(AttributeFactory::PropertyAllocSize);
- return add(new (memory) AttributeList(attrName, attrRange,
- scopeName, scopeLoc,
- getterId, setterId,
- syntaxUsed));
+ return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
+ getterId, setterId, syntaxUsed));
}
};
-/// ParsedAttributes - A collection of parsed attributes. Currently
-/// we don't differentiate between the various attribute syntaxes,
-/// which is basically silly.
-///
-/// Right now this is a very lightweight container, but the expectation
-/// is that this will become significantly more serious.
-class ParsedAttributes {
+class ParsedAttributesView {
+ using VecTy = llvm::TinyPtrVector<ParsedAttr *>;
+ using SizeType = decltype(std::declval<VecTy>().size());
+
public:
- ParsedAttributes(AttributeFactory &factory)
- : pool(factory), list(nullptr) {
+ bool empty() const { return AttrList.empty(); }
+ SizeType size() const { return AttrList.size(); }
+ ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; }
+ const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; }
+
+ void addAtStart(ParsedAttr *newAttr) {
+ assert(newAttr);
+ AttrList.insert(AttrList.begin(), newAttr);
+ }
+ void addAtEnd(ParsedAttr *newAttr) {
+ assert(newAttr);
+ AttrList.push_back(newAttr);
}
- ParsedAttributes(const ParsedAttributes &) = delete;
+ void remove(ParsedAttr *ToBeRemoved) {
+ assert(is_contained(AttrList, ToBeRemoved) &&
+ "Cannot remove attribute that isn't in the list");
+ AttrList.erase(llvm::find(AttrList, ToBeRemoved));
+ }
- AttributePool &getPool() const { return pool; }
+ void clearListOnly() { AttrList.clear(); }
- bool empty() const { return list == nullptr; }
+ struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
+ std::random_access_iterator_tag,
+ ParsedAttr> {
+ iterator() : iterator_adaptor_base(nullptr) {}
+ iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
+ reference operator*() { return **I; }
+ friend class ParsedAttributesView;
+ };
+ struct const_iterator
+ : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
+ std::random_access_iterator_tag,
+ ParsedAttr> {
+ const_iterator() : iterator_adaptor_base(nullptr) {}
+ const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {}
+
+ reference operator*() const { return **I; }
+ friend class ParsedAttributesView;
+ };
- void add(AttributeList *newAttr) {
- assert(newAttr);
- assert(newAttr->getNext() == nullptr);
- newAttr->setNext(list);
- list = newAttr;
+ void addAll(iterator B, iterator E) {
+ AttrList.insert(AttrList.begin(), B.I, E.I);
}
- void addAll(AttributeList *newList) {
- if (!newList) return;
-
- AttributeList *lastInNewList = newList;
- while (AttributeList *next = lastInNewList->getNext())
- lastInNewList = next;
+ void addAll(const_iterator B, const_iterator E) {
+ AttrList.insert(AttrList.begin(), B.I, E.I);
+ }
- lastInNewList->setNext(list);
- list = newList;
+ void addAllAtEnd(iterator B, iterator E) {
+ AttrList.insert(AttrList.end(), B.I, E.I);
}
- void addAllAtEnd(AttributeList *newList) {
- if (!list) {
- list = newList;
- return;
- }
+ void addAllAtEnd(const_iterator B, const_iterator E) {
+ AttrList.insert(AttrList.end(), B.I, E.I);
+ }
- AttributeList *lastInList = list;
- while (AttributeList *next = lastInList->getNext())
- lastInList = next;
+ iterator begin() { return iterator(AttrList.begin()); }
+ const_iterator begin() const { return const_iterator(AttrList.begin()); }
+ iterator end() { return iterator(AttrList.end()); }
+ const_iterator end() const { return const_iterator(AttrList.end()); }
- lastInList->setNext(newList);
+ bool hasAttribute(ParsedAttr::Kind K) const {
+ return llvm::any_of(
+ AttrList, [K](const ParsedAttr *AL) { return AL->getKind() == K; });
}
- void set(AttributeList *newList) {
- list = newList;
- }
+private:
+ VecTy AttrList;
+};
+
+/// ParsedAttributes - A collection of parsed attributes. Currently
+/// we don't differentiate between the various attribute syntaxes,
+/// which is basically silly.
+///
+/// Right now this is a very lightweight container, but the expectation
+/// is that this will become significantly more serious.
+class ParsedAttributes : public ParsedAttributesView {
+public:
+ ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
+ ParsedAttributes(const ParsedAttributes &) = delete;
+
+ AttributePool &getPool() const { return pool; }
void takeAllFrom(ParsedAttributes &attrs) {
- addAll(attrs.list);
- attrs.list = nullptr;
+ addAll(attrs.begin(), attrs.end());
+ attrs.clearListOnly();
pool.takeAllFrom(attrs.pool);
}
- void clear() { list = nullptr; pool.clear(); }
- AttributeList *getList() const { return list; }
-
- void clearListOnly() { list = nullptr; }
-
- /// Returns a reference to the attribute list. Try not to introduce
- /// dependencies on this method, it may not be long-lived.
- AttributeList *&getListRef() { return list; }
+ void clear() {
+ clearListOnly();
+ pool.clear();
+ }
/// Add attribute with expression arguments.
- AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ArgsUnion *args, unsigned numArgs,
- AttributeList::Syntax syntax,
- SourceLocation ellipsisLoc = SourceLocation()) {
- AttributeList *attr =
- pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
- syntax, ellipsisLoc);
- add(attr);
+ ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ ArgsUnion *args, unsigned numArgs,
+ ParsedAttr::Syntax syntax,
+ SourceLocation ellipsisLoc = SourceLocation()) {
+ ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
+ args, numArgs, syntax, ellipsisLoc);
+ addAtStart(attr);
return attr;
}
/// Add availability attribute.
- AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Param,
- const AvailabilityChange &introduced,
- const AvailabilityChange &deprecated,
- const AvailabilityChange &obsoleted,
- SourceLocation unavailable,
- const Expr *MessageExpr,
- AttributeList::Syntax syntax,
- SourceLocation strict, const Expr *ReplacementExpr) {
- AttributeList *attr =
- pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
- deprecated, obsoleted, unavailable, MessageExpr, syntax,
- strict, ReplacementExpr);
- add(attr);
+ ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *Param, const AvailabilityChange &introduced,
+ const AvailabilityChange &deprecated,
+ const AvailabilityChange &obsoleted,
+ SourceLocation unavailable, const Expr *MessageExpr,
+ ParsedAttr::Syntax syntax, SourceLocation strict,
+ const Expr *ReplacementExpr) {
+ ParsedAttr *attr = pool.create(
+ attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
+ obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr);
+ addAtStart(attr);
return attr;
}
/// Add objc_bridge_related attribute.
- AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Param1,
- IdentifierLoc *Param2,
- IdentifierLoc *Param3,
- AttributeList::Syntax syntax) {
- AttributeList *attr =
- pool.create(attrName, attrRange, scopeName, scopeLoc,
- Param1, Param2, Param3, syntax);
- add(attr);
+ ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *Param1, IdentifierLoc *Param2,
+ IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
+ ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
+ Param1, Param2, Param3, syntax);
+ addAtStart(attr);
return attr;
}
/// Add type_tag_for_datatype attribute.
- AttributeList *addNewTypeTagForDatatype(
- IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *argumentKind, ParsedType matchingCType,
- bool layoutCompatible, bool mustBeNull,
- AttributeList::Syntax syntax) {
- AttributeList *attr =
- pool.createTypeTagForDatatype(attrName, attrRange,
- scopeName, scopeLoc,
- argumentKind, matchingCType,
- layoutCompatible, mustBeNull, syntax);
- add(attr);
+ ParsedAttr *
+ addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierLoc *argumentKind,
+ ParsedType matchingCType, bool layoutCompatible,
+ bool mustBeNull, ParsedAttr::Syntax syntax) {
+ ParsedAttr *attr = pool.createTypeTagForDatatype(
+ attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
+ layoutCompatible, mustBeNull, syntax);
+ addAtStart(attr);
return attr;
}
/// Add an attribute with a single type argument.
- AttributeList *
- addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
- AttributeList *attr =
- pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
- typeArg, syntaxUsed);
- add(attr);
+ ParsedAttr *addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ ParsedType typeArg,
+ ParsedAttr::Syntax syntaxUsed) {
+ ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName,
+ scopeLoc, typeArg, syntaxUsed);
+ addAtStart(attr);
return attr;
}
/// Add microsoft __delspec(property) attribute.
- AttributeList *
+ ParsedAttr *
addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierInfo *getterId, IdentifierInfo *setterId,
- AttributeList::Syntax syntaxUsed) {
- AttributeList *attr =
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ IdentifierInfo *getterId, IdentifierInfo *setterId,
+ ParsedAttr::Syntax syntaxUsed) {
+ ParsedAttr *attr =
pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
getterId, setterId, syntaxUsed);
- add(attr);
+ addAtStart(attr);
return attr;
}
private:
mutable AttributePool pool;
- AttributeList *list;
};
/// These constants match the enumerated choices of
@@ -910,9 +924,8 @@ enum AttributeDeclKind {
ExpectedFunctionVariableOrClass,
ExpectedKernelFunction,
ExpectedFunctionWithProtoType,
- ExpectedForMaybeUnused,
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SEMA_ATTRIBUTELIST_H
diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h
index 01a4ab3f37a51..f79157ba813e6 100644
--- a/include/clang/Sema/ParsedTemplate.h
+++ b/include/clang/Sema/ParsedTemplate.h
@@ -26,32 +26,32 @@
#include <new>
namespace clang {
- /// \brief Represents the parsed form of a C++ template argument.
+ /// Represents the parsed form of a C++ template argument.
class ParsedTemplateArgument {
public:
- /// \brief Describes the kind of template argument that was parsed.
+ /// Describes the kind of template argument that was parsed.
enum KindType {
- /// \brief A template type parameter, stored as a type.
+ /// A template type parameter, stored as a type.
Type,
- /// \brief A non-type template parameter, stored as an expression.
+ /// A non-type template parameter, stored as an expression.
NonType,
- /// \brief A template template argument, stored as a template name.
+ /// A template template argument, stored as a template name.
Template
};
- /// \brief Build an empty template argument.
+ /// Build an empty template argument.
///
/// This template argument is invalid.
ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
- /// \brief Create a template type argument or non-type template argument.
+ /// Create a template type argument or non-type template argument.
///
/// \param Arg the template type argument or non-type template argument.
/// \param Loc the location of the type.
ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
: Kind(Kind), Arg(Arg), Loc(Loc) { }
- /// \brief Create a template template argument.
+ /// Create a template template argument.
///
/// \param SS the C++ scope specifier that precedes the template name, if
/// any.
@@ -67,34 +67,34 @@ namespace clang {
Arg(Template.getAsOpaquePtr()),
SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
- /// \brief Determine whether the given template argument is invalid.
+ /// Determine whether the given template argument is invalid.
bool isInvalid() const { return Arg == nullptr; }
- /// \brief Determine what kind of template argument we have.
+ /// Determine what kind of template argument we have.
KindType getKind() const { return Kind; }
- /// \brief Retrieve the template type argument's type.
+ /// Retrieve the template type argument's type.
ParsedType getAsType() const {
assert(Kind == Type && "Not a template type argument");
return ParsedType::getFromOpaquePtr(Arg);
}
- /// \brief Retrieve the non-type template argument's expression.
+ /// Retrieve the non-type template argument's expression.
Expr *getAsExpr() const {
assert(Kind == NonType && "Not a non-type template argument");
return static_cast<Expr*>(Arg);
}
- /// \brief Retrieve the template template argument's template name.
+ /// Retrieve the template template argument's template name.
ParsedTemplateTy getAsTemplate() const {
assert(Kind == Template && "Not a template template argument");
return ParsedTemplateTy::getFromOpaquePtr(Arg);
}
- /// \brief Retrieve the location of the template argument.
+ /// Retrieve the location of the template argument.
SourceLocation getLocation() const { return Loc; }
- /// \brief Retrieve the nested-name-specifier that precedes the template
+ /// Retrieve the nested-name-specifier that precedes the template
/// name in a template template argument.
const CXXScopeSpec &getScopeSpec() const {
assert(Kind == Template &&
@@ -102,7 +102,7 @@ namespace clang {
return SS;
}
- /// \brief Retrieve the location of the ellipsis that makes a template
+ /// Retrieve the location of the ellipsis that makes a template
/// template argument into a pack expansion.
SourceLocation getEllipsisLoc() const {
assert(Kind == Template &&
@@ -110,7 +110,7 @@ namespace clang {
return EllipsisLoc;
}
- /// \brief Retrieve a pack expansion of the given template template
+ /// Retrieve a pack expansion of the given template template
/// argument.
///
/// \param EllipsisLoc The location of the ellipsis.
@@ -120,24 +120,24 @@ namespace clang {
private:
KindType Kind;
- /// \brief The actual template argument representation, which may be
+ /// The actual template argument representation, which may be
/// an \c Sema::TypeTy* (for a type), an Expr* (for an
/// expression), or an Sema::TemplateTy (for a template).
void *Arg;
- /// \brief The nested-name-specifier that can accompany a template template
+ /// The nested-name-specifier that can accompany a template template
/// argument.
CXXScopeSpec SS;
- /// \brief the location of the template argument.
+ /// the location of the template argument.
SourceLocation Loc;
- /// \brief The ellipsis location that can accompany a template template
+ /// The ellipsis location that can accompany a template template
/// argument (turning it into a template template argument expansion).
SourceLocation EllipsisLoc;
};
- /// \brief Information about a template-id annotation
+ /// Information about a template-id annotation
/// token.
///
/// A template-id annotation token contains the template declaration,
@@ -149,7 +149,7 @@ namespace clang {
: private llvm::TrailingObjects<TemplateIdAnnotation,
ParsedTemplateArgument> {
friend TrailingObjects;
- /// \brief The nested-name-specifier that precedes the template name.
+ /// The nested-name-specifier that precedes the template name.
CXXScopeSpec SS;
/// TemplateKWLoc - The location of the template keyword.
@@ -184,12 +184,12 @@ namespace clang {
/// NumArgs - The number of template arguments.
unsigned NumArgs;
- /// \brief Retrieves a pointer to the template arguments
+ /// Retrieves a pointer to the template arguments
ParsedTemplateArgument *getTemplateArgs() {
return getTrailingObjects<ParsedTemplateArgument>();
}
- /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
+ /// Creates a new TemplateIdAnnotation with NumArgs arguments and
/// appends it to List.
static TemplateIdAnnotation *
Create(CXXScopeSpec SS, SourceLocation TemplateKWLoc,
@@ -199,8 +199,7 @@ namespace clang {
SourceLocation LAngleLoc, SourceLocation RAngleLoc,
ArrayRef<ParsedTemplateArgument> TemplateArgs,
SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) {
-
- TemplateIdAnnotation *TemplateId = new (std::malloc(
+ TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
TemplateIdAnnotation(SS, TemplateKWLoc, TemplateNameLoc, Name,
OperatorKind, OpaqueTemplateName, TemplateKind,
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
index cd58a9910f98e..a3379ff34f123 100644
--- a/include/clang/Sema/Scope.h
+++ b/include/clang/Sema/Scope.h
@@ -1,4 +1,4 @@
-//===--- Scope.h - Scope interface ------------------------------*- C++ -*-===//
+//===- Scope.h - Scope interface --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,101 +14,102 @@
#ifndef LLVM_CLANG_SEMA_SCOPE_H
#define LLVM_CLANG_SEMA_SCOPE_H
-#include "clang/AST/Decl.h"
#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
+#include <cassert>
namespace llvm {
class raw_ostream;
-}
+} // namespace llvm
namespace clang {
class Decl;
+class DeclContext;
class UsingDirectiveDecl;
class VarDecl;
/// Scope - A scope is a transient data structure that is used while parsing the
/// program. It assists with resolving identifiers to the appropriate
/// declaration.
-///
class Scope {
public:
/// ScopeFlags - These are bitfields that are or'd together when creating a
/// scope, which defines the sorts of things the scope contains.
enum ScopeFlags {
- /// \brief This indicates that the scope corresponds to a function, which
+ /// This indicates that the scope corresponds to a function, which
/// means that labels are set here.
FnScope = 0x01,
- /// \brief This is a while, do, switch, for, etc that can have break
+ /// This is a while, do, switch, for, etc that can have break
/// statements embedded into it.
BreakScope = 0x02,
- /// \brief This is a while, do, for, which can have continue statements
+ /// This is a while, do, for, which can have continue statements
/// embedded into it.
ContinueScope = 0x04,
- /// \brief This is a scope that can contain a declaration. Some scopes
+ /// This is a scope that can contain a declaration. Some scopes
/// just contain loop constructs but don't contain decls.
DeclScope = 0x08,
- /// \brief The controlling scope in a if/switch/while/for statement.
+ /// The controlling scope in a if/switch/while/for statement.
ControlScope = 0x10,
- /// \brief The scope of a struct/union/class definition.
+ /// The scope of a struct/union/class definition.
ClassScope = 0x20,
- /// \brief This is a scope that corresponds to a block/closure object.
+ /// This is a scope that corresponds to a block/closure object.
/// Blocks serve as top-level scopes for some objects like labels, they
/// also prevent things like break and continue. BlockScopes always have
/// the FnScope and DeclScope flags set as well.
BlockScope = 0x40,
- /// \brief This is a scope that corresponds to the
+ /// This is a scope that corresponds to the
/// template parameters of a C++ template. Template parameter
/// scope starts at the 'template' keyword and ends when the
/// template declaration ends.
TemplateParamScope = 0x80,
- /// \brief This is a scope that corresponds to the
+ /// This is a scope that corresponds to the
/// parameters within a function prototype.
FunctionPrototypeScope = 0x100,
- /// \brief This is a scope that corresponds to the parameters within
+ /// This is a scope that corresponds to the parameters within
/// a function prototype for a function declaration (as opposed to any
/// other kind of function declarator). Always has FunctionPrototypeScope
/// set as well.
FunctionDeclarationScope = 0x200,
- /// \brief This is a scope that corresponds to the Objective-C
+ /// This is a scope that corresponds to the Objective-C
/// \@catch statement.
AtCatchScope = 0x400,
- /// \brief This scope corresponds to an Objective-C method body.
+ /// This scope corresponds to an Objective-C method body.
/// It always has FnScope and DeclScope set as well.
ObjCMethodScope = 0x800,
- /// \brief This is a scope that corresponds to a switch statement.
+ /// This is a scope that corresponds to a switch statement.
SwitchScope = 0x1000,
- /// \brief This is the scope of a C++ try statement.
+ /// This is the scope of a C++ try statement.
TryScope = 0x2000,
- /// \brief This is the scope for a function-level C++ try or catch scope.
+ /// This is the scope for a function-level C++ try or catch scope.
FnTryCatchScope = 0x4000,
- /// \brief This is the scope of OpenMP executable directive.
+ /// This is the scope of OpenMP executable directive.
OpenMPDirectiveScope = 0x8000,
- /// \brief This is the scope of some OpenMP loop directive.
+ /// This is the scope of some OpenMP loop directive.
OpenMPLoopDirectiveScope = 0x10000,
- /// \brief This is the scope of some OpenMP simd directive.
+ /// This is the scope of some OpenMP simd directive.
/// For example, it is used for 'omp simd', 'omp for simd'.
/// This flag is propagated to children scopes.
OpenMPSimdDirectiveScope = 0x20000,
@@ -131,6 +132,7 @@ public:
/// We are between inheritance colon and the real class/struct definition scope.
ClassInheritanceScope = 0x800000,
};
+
private:
/// The parent scope for this scope. This is null for the translation-unit
/// scope.
@@ -144,7 +146,7 @@ private:
/// depth 0.
unsigned short Depth;
- /// \brief Declarations with static linkage are mangled with the number of
+ /// Declarations with static linkage are mangled with the number of
/// scopes seen as a component.
unsigned short MSLastManglingNumber;
@@ -185,7 +187,7 @@ private:
/// popped, these declarations are removed from the IdentifierTable's notion
/// of current declaration. It is up to the current Action implementation to
/// implement these semantics.
- typedef llvm::SmallPtrSet<Decl *, 32> DeclSetTy;
+ using DeclSetTy = llvm::SmallPtrSet<Decl *, 32>;
DeclSetTy DeclsInScope;
/// The DeclContext with which this scope is associated. For
@@ -193,10 +195,10 @@ private:
/// entity of a function scope is a function, etc.
DeclContext *Entity;
- typedef SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy;
+ using UsingDirectivesTy = SmallVector<UsingDirectiveDecl *, 2>;
UsingDirectivesTy UsingDirectives;
- /// \brief Used to determine if errors occurred in this scope.
+ /// Used to determine if errors occurred in this scope.
DiagnosticErrorTrap ErrorTrap;
/// A lattice consisting of undefined, a single NRVO candidate variable in
@@ -207,25 +209,23 @@ private:
public:
Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
- : ErrorTrap(Diag) {
+ : ErrorTrap(Diag) {
Init(Parent, ScopeFlags);
}
/// getFlags - Return the flags for this scope.
- ///
unsigned getFlags() const { return Flags; }
+
void setFlags(unsigned F) { setFlags(getParent(), F); }
/// isBlockScope - Return true if this scope correspond to a closure.
bool isBlockScope() const { return Flags & BlockScope; }
/// getParent - Return the scope that this is nested in.
- ///
const Scope *getParent() const { return AnyParent; }
Scope *getParent() { return AnyParent; }
/// getFnParent - Return the closest scope that is a function body.
- ///
const Scope *getFnParent() const { return FnParent; }
Scope *getFnParent() { return FnParent; }
@@ -259,6 +259,9 @@ public:
Scope *getTemplateParamParent() { return TemplateParamParent; }
const Scope *getTemplateParamParent() const { return TemplateParamParent; }
+ /// Returns the depth of this scope. The translation-unit has scope depth 0.
+ unsigned getDepth() const { return Depth; }
+
/// Returns the number of function prototype scopes in this scope
/// chain.
unsigned getFunctionPrototypeDepth() const {
@@ -272,10 +275,12 @@ public:
return PrototypeIndex++;
}
- typedef llvm::iterator_range<DeclSetTy::iterator> decl_range;
+ using decl_range = llvm::iterator_range<DeclSetTy::iterator>;
+
decl_range decls() const {
return decl_range(DeclsInScope.begin(), DeclsInScope.end());
}
+
bool decl_empty() const { return DeclsInScope.empty(); }
void AddDecl(Decl *D) {
@@ -365,7 +370,6 @@ public:
return false;
}
-
/// isTemplateParamScope - Return true if this scope is a C++
/// template parameter scope.
bool isTemplateParamScope() const {
@@ -397,12 +401,12 @@ public:
return false;
}
- /// \brief Determines whether this scope is the OpenMP directive scope
+ /// Determines whether this scope is the OpenMP directive scope
bool isOpenMPDirectiveScope() const {
return (getFlags() & Scope::OpenMPDirectiveScope);
}
- /// \brief Determine whether this scope is some OpenMP loop directive scope
+ /// Determine whether this scope is some OpenMP loop directive scope
/// (for example, 'omp for', 'omp simd').
bool isOpenMPLoopDirectiveScope() const {
if (getFlags() & Scope::OpenMPLoopDirectiveScope) {
@@ -413,34 +417,34 @@ public:
return false;
}
- /// \brief Determine whether this scope is (or is nested into) some OpenMP
+ /// Determine whether this scope is (or is nested into) some OpenMP
/// loop simd directive scope (for example, 'omp simd', 'omp for simd').
bool isOpenMPSimdDirectiveScope() const {
return getFlags() & Scope::OpenMPSimdDirectiveScope;
}
- /// \brief Determine whether this scope is a loop having OpenMP loop
+ /// Determine whether this scope is a loop having OpenMP loop
/// directive attached.
bool isOpenMPLoopScope() const {
const Scope *P = getParent();
return P && P->isOpenMPLoopDirectiveScope();
}
- /// \brief Determine whether this scope is a C++ 'try' block.
+ /// Determine whether this scope is a C++ 'try' block.
bool isTryScope() const { return getFlags() & Scope::TryScope; }
- /// \brief Determine whether this scope is a SEH '__try' block.
+ /// Determine whether this scope is a SEH '__try' block.
bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
- /// \brief Determine whether this scope is a SEH '__except' block.
+ /// Determine whether this scope is a SEH '__except' block.
bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; }
- /// \brief Determine whether this scope is a compound statement scope.
+ /// Determine whether this scope is a compound statement scope.
bool isCompoundStmtScope() const {
return getFlags() & Scope::CompoundStmtScope;
}
- /// \brief Returns if rhs has a higher scope depth than this.
+ /// Returns if rhs has a higher scope depth than this.
///
/// The caller is responsible for calling this only if one of the two scopes
/// is an ancestor of the other.
@@ -454,8 +458,8 @@ public:
UsingDirectives.push_back(UDir);
}
- typedef llvm::iterator_range<UsingDirectivesTy::iterator>
- using_directives_range;
+ using using_directives_range =
+ llvm::iterator_range<UsingDirectivesTy::iterator>;
using_directives_range using_directives() {
return using_directives_range(UsingDirectives.begin(),
@@ -474,25 +478,23 @@ public:
}
void setNoNRVO() {
- NRVO.setInt(1);
+ NRVO.setInt(true);
NRVO.setPointer(nullptr);
}
void mergeNRVOIntoParent();
/// Init - This is used by the parser to implement scope caching.
- ///
void Init(Scope *parent, unsigned flags);
- /// \brief Sets up the specified scope flags and adjusts the scope state
+ /// Sets up the specified scope flags and adjusts the scope state
/// variables accordingly.
- ///
void AddFlags(unsigned Flags);
void dumpImpl(raw_ostream &OS) const;
void dump() const;
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SEMA_SCOPE_H
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index c707a3e8ef074..5eac2845fd33e 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -1,4 +1,4 @@
-//===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===//
+//===- ScopeInfo.h - Information about a semantic context -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,48 +18,62 @@
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Basic/CapturedStmt.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/CleanupInfo.h"
-#include "clang/Sema/Ownership.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
+#include <cassert>
+#include <utility>
namespace clang {
-class Decl;
class BlockDecl;
class CapturedDecl;
class CXXMethodDecl;
-class FieldDecl;
-class ObjCPropertyDecl;
-class IdentifierInfo;
+class CXXRecordDecl;
class ImplicitParamDecl;
-class LabelDecl;
+class NamedDecl;
+class ObjCIvarRefExpr;
+class ObjCMessageExpr;
+class ObjCPropertyDecl;
+class ObjCPropertyRefExpr;
+class ParmVarDecl;
+class RecordDecl;
class ReturnStmt;
class Scope;
+class Stmt;
class SwitchStmt;
-class TemplateTypeParmDecl;
class TemplateParameterList;
+class TemplateTypeParmDecl;
class VarDecl;
-class ObjCIvarRefExpr;
-class ObjCPropertyRefExpr;
-class ObjCMessageExpr;
namespace sema {
-/// \brief Contains information about the compound statement currently being
+/// Contains information about the compound statement currently being
/// parsed.
class CompoundScopeInfo {
public:
- CompoundScopeInfo()
- : HasEmptyLoopBodies(false) { }
-
- /// \brief Whether this compound stamement contains `for' or `while' loops
+ /// Whether this compound stamement contains `for' or `while' loops
/// with empty bodies.
- bool HasEmptyLoopBodies;
+ bool HasEmptyLoopBodies = false;
+
+ /// Whether this compound statement corresponds to a GNU statement
+ /// expression.
+ bool IsStmtExpr;
+
+ CompoundScopeInfo(bool IsStmtExpr) : IsStmtExpr(IsStmtExpr) {}
void setHasEmptyLoopBodies() {
HasEmptyLoopBodies = true;
@@ -74,10 +88,10 @@ public:
PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
const Stmt *stmt)
- : PD(PD), Loc(Loc), stmt(stmt) {}
+ : PD(PD), Loc(Loc), stmt(stmt) {}
};
-/// \brief Retains information about a function, method, or block that is
+/// Retains information about a function, method, or block that is
/// currently being parsed.
class FunctionScopeInfo {
protected:
@@ -89,30 +103,29 @@ protected:
};
public:
- /// \brief What kind of scope we are describing.
- ///
+ /// What kind of scope we are describing.
ScopeKind Kind : 3;
- /// \brief Whether this function contains a VLA, \@try, try, C++
+ /// Whether this function contains a VLA, \@try, try, C++
/// initializer, or anything else that can't be jumped past.
bool HasBranchProtectedScope : 1;
- /// \brief Whether this function contains any switches or direct gotos.
+ /// Whether this function contains any switches or direct gotos.
bool HasBranchIntoScope : 1;
- /// \brief Whether this function contains any indirect gotos.
+ /// Whether this function contains any indirect gotos.
bool HasIndirectGoto : 1;
- /// \brief Whether a statement was dropped because it was invalid.
+ /// Whether a statement was dropped because it was invalid.
bool HasDroppedStmt : 1;
- /// \brief True if current scope is for OpenMP declare reduction combiner.
+ /// True if current scope is for OpenMP declare reduction combiner.
bool HasOMPDeclareReductionCombiner : 1;
- /// \brief Whether there is a fallthrough statement in this function.
+ /// Whether there is a fallthrough statement in this function.
bool HasFallthroughStmt : 1;
- /// \brief Whether we make reference to a declaration that could be
+ /// Whether we make reference to a declaration that could be
/// unavailable.
bool HasPotentialAvailabilityViolations : 1;
@@ -123,6 +136,7 @@ public:
/// True when this is a method marked as a designated initializer.
bool ObjCIsDesignatedInit : 1;
+
/// This starts true for a method marked as designated initializer and will
/// be set to false if there is an invocation to a designated initializer of
/// the super class.
@@ -132,15 +146,16 @@ public:
/// initializer within a class that has at least one initializer marked as a
/// designated initializer.
bool ObjCIsSecondaryInit : 1;
+
/// This starts true for a secondary initializer method and will be set to
/// false if there is an invocation of an initializer on 'self'.
bool ObjCWarnForNoInitDelegation : 1;
- /// \brief True only when this function has not already built, or attempted
+ /// True only when this function has not already built, or attempted
/// to build, the initial and final coroutine suspend points
bool NeedsCoroutineSuspends : 1;
- /// \brief An enumeration represeting the kind of the first coroutine statement
+ /// An enumeration represeting the kind of the first coroutine statement
/// in the function. One of co_return, co_await, or co_yield.
unsigned char FirstCoroutineStmtKind : 2;
@@ -157,36 +172,44 @@ public:
/// First SEH '__try' statement in the current function.
SourceLocation FirstSEHTryLoc;
- /// \brief Used to determine if errors occurred in this function or block.
+ /// Used to determine if errors occurred in this function or block.
DiagnosticErrorTrap ErrorTrap;
+ /// A SwitchStmt, along with a flag indicating if its list of case statements
+ /// is incomplete (because we dropped an invalid one while parsing).
+ using SwitchInfo = llvm::PointerIntPair<SwitchStmt*, 1, bool>;
+
/// SwitchStack - This is the current set of active switch statements in the
/// block.
- SmallVector<SwitchStmt*, 8> SwitchStack;
+ SmallVector<SwitchInfo, 8> SwitchStack;
- /// \brief The list of return statements that occur within the function or
+ /// The list of return statements that occur within the function or
/// block, if there is any chance of applying the named return value
/// optimization, or if we need to infer a return type.
SmallVector<ReturnStmt*, 4> Returns;
- /// \brief The promise object for this coroutine, if any.
+ /// The promise object for this coroutine, if any.
VarDecl *CoroutinePromise = nullptr;
- /// \brief The initial and final coroutine suspend points.
+ /// A mapping between the coroutine function parameters that were moved
+ /// to the coroutine frame, and their move statements.
+ llvm::SmallMapVector<ParmVarDecl *, Stmt *, 4> CoroutineParameterMoves;
+
+ /// The initial and final coroutine suspend points.
std::pair<Stmt *, Stmt *> CoroutineSuspends;
- /// \brief The stack of currently active compound stamement scopes in the
+ /// The stack of currently active compound stamement scopes in the
/// function.
SmallVector<CompoundScopeInfo, 4> CompoundScopes;
- /// \brief A list of PartialDiagnostics created but delayed within the
+ /// A list of PartialDiagnostics created but delayed within the
/// current function scope. These diagnostics are vetted for reachability
/// prior to being emitted.
SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
- /// \brief A list of parameters which have the nonnull attribute and are
+ /// A list of parameters which have the nonnull attribute and are
/// modified in the function.
- llvm::SmallPtrSet<const ParmVarDecl*, 8> ModifiedNonNullParams;
+ llvm::SmallPtrSet<const ParmVarDecl *, 8> ModifiedNonNullParams;
public:
/// Represents a simple identification of a weak object.
@@ -218,14 +241,14 @@ public:
/// identify the object in memory.
///
/// \sa isExactProfile()
- typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
+ using BaseInfoTy = llvm::PointerIntPair<const NamedDecl *, 1, bool>;
BaseInfoTy Base;
/// The "property" decl, as described in the class documentation.
///
/// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
/// case of "implicit" properties (regular methods accessed via dot syntax).
- const NamedDecl *Property;
+ const NamedDecl *Property = nullptr;
/// Used to find the proper base profile for a given base expression.
static BaseInfoTy getBaseInfo(const Expr *BaseE);
@@ -270,12 +293,14 @@ public:
static inline WeakObjectProfileTy getEmptyKey() {
return WeakObjectProfileTy();
}
+
static inline WeakObjectProfileTy getTombstoneKey() {
return WeakObjectProfileTy::getSentinel();
}
static unsigned getHashValue(const WeakObjectProfileTy &Val) {
- typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
+ using Pair = std::pair<BaseInfoTy, const NamedDecl *>;
+
return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
Val.Property));
}
@@ -295,6 +320,7 @@ public:
/// Part of the implementation of -Wrepeated-use-of-weak.
class WeakUseTy {
llvm::PointerIntPair<const Expr *, 1, bool> Rep;
+
public:
WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
@@ -310,14 +336,14 @@ public:
/// Used to collect uses of a particular weak object in a function body.
///
/// Part of the implementation of -Wrepeated-use-of-weak.
- typedef SmallVector<WeakUseTy, 4> WeakUseVector;
+ using WeakUseVector = SmallVector<WeakUseTy, 4>;
/// Used to collect all uses of weak objects in a function body.
///
/// Part of the implementation of -Wrepeated-use-of-weak.
- typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
- WeakObjectProfileTy::DenseMapInfo>
- WeakObjectUseMap;
+ using WeakObjectUseMap =
+ llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
+ WeakObjectProfileTy::DenseMapInfo>;
private:
/// Used to collect all uses of weak objects in this function body.
@@ -329,6 +355,18 @@ protected:
FunctionScopeInfo(const FunctionScopeInfo&) = default;
public:
+ FunctionScopeInfo(DiagnosticsEngine &Diag)
+ : Kind(SK_Function), HasBranchProtectedScope(false),
+ HasBranchIntoScope(false), HasIndirectGoto(false),
+ HasDroppedStmt(false), HasOMPDeclareReductionCombiner(false),
+ HasFallthroughStmt(false), HasPotentialAvailabilityViolations(false),
+ ObjCShouldCallSuper(false), ObjCIsDesignatedInit(false),
+ ObjCWarnForNoDesignatedInitChain(false), ObjCIsSecondaryInit(false),
+ ObjCWarnForNoInitDelegation(false), NeedsCoroutineSuspends(true),
+ ErrorTrap(Diag) {}
+
+ virtual ~FunctionScopeInfo();
+
/// Record that a weak object was accessed.
///
/// Part of the implementation of -Wrepeated-use-of-weak.
@@ -430,179 +468,165 @@ public:
CoroutineSuspends.second = Final;
}
- FunctionScopeInfo(DiagnosticsEngine &Diag)
- : Kind(SK_Function),
- HasBranchProtectedScope(false),
- HasBranchIntoScope(false),
- HasIndirectGoto(false),
- HasDroppedStmt(false),
- HasOMPDeclareReductionCombiner(false),
- HasFallthroughStmt(false),
- HasPotentialAvailabilityViolations(false),
- ObjCShouldCallSuper(false),
- ObjCIsDesignatedInit(false),
- ObjCWarnForNoDesignatedInitChain(false),
- ObjCIsSecondaryInit(false),
- ObjCWarnForNoInitDelegation(false),
- NeedsCoroutineSuspends(true),
- ErrorTrap(Diag) { }
-
- virtual ~FunctionScopeInfo();
-
- /// \brief Clear out the information in this function scope, making it
+ /// Clear out the information in this function scope, making it
/// suitable for reuse.
void Clear();
};
-class CapturingScopeInfo : public FunctionScopeInfo {
-protected:
- CapturingScopeInfo(const CapturingScopeInfo&) = default;
+class Capture {
+ // There are three categories of capture: capturing 'this', capturing
+ // local variables, and C++1y initialized captures (which can have an
+ // arbitrary initializer, and don't really capture in the traditional
+ // sense at all).
+ //
+ // There are three ways to capture a local variable:
+ // - capture by copy in the C++11 sense,
+ // - capture by reference in the C++11 sense, and
+ // - __block capture.
+ // Lambdas explicitly specify capture by copy or capture by reference.
+ // For blocks, __block capture applies to variables with that annotation,
+ // variables of reference type are captured by reference, and other
+ // variables are captured by copy.
+ enum CaptureKind {
+ Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA
+ };
+ enum {
+ IsNestedCapture = 0x1,
+ IsThisCaptured = 0x2
+ };
+
+ /// The variable being captured (if we are not capturing 'this') and whether
+ /// this is a nested capture, and whether we are capturing 'this'
+ llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis;
+
+ /// Expression to initialize a field of the given type, and the kind of
+ /// capture (if this is a capture and not an init-capture). The expression
+ /// is only required if we are capturing ByVal and the variable's type has
+ /// a non-trivial copy constructor.
+ llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind;
+
+ /// The source location at which the first capture occurred.
+ SourceLocation Loc;
+
+ /// The location of the ellipsis that expands a parameter pack.
+ SourceLocation EllipsisLoc;
+
+ /// The type as it was captured, which is in effect the type of the
+ /// non-static data member that would hold the capture.
+ QualType CaptureType;
+
+ /// Whether an explicit capture has been odr-used in the body of the
+ /// lambda.
+ bool ODRUsed = false;
+
+ /// Whether an explicit capture has been non-odr-used in the body of
+ /// the lambda.
+ bool NonODRUsed = false;
public:
- enum ImplicitCaptureStyle {
- ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
- ImpCap_CapturedRegion
- };
+ Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
+ SourceLocation Loc, SourceLocation EllipsisLoc,
+ QualType CaptureType, Expr *Cpy)
+ : VarAndNestedAndThis(Var, IsNested ? IsNestedCapture : 0),
+ InitExprAndCaptureKind(
+ Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef
+ : Cap_ByCopy),
+ Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
- ImplicitCaptureStyle ImpCaptureStyle;
+ enum IsThisCapture { ThisCapture };
+ Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
+ QualType CaptureType, Expr *Cpy, const bool ByCopy)
+ : VarAndNestedAndThis(
+ nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))),
+ InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef),
+ Loc(Loc), CaptureType(CaptureType) {}
- class Capture {
- // There are three categories of capture: capturing 'this', capturing
- // local variables, and C++1y initialized captures (which can have an
- // arbitrary initializer, and don't really capture in the traditional
- // sense at all).
- //
- // There are three ways to capture a local variable:
- // - capture by copy in the C++11 sense,
- // - capture by reference in the C++11 sense, and
- // - __block capture.
- // Lambdas explicitly specify capture by copy or capture by reference.
- // For blocks, __block capture applies to variables with that annotation,
- // variables of reference type are captured by reference, and other
- // variables are captured by copy.
- enum CaptureKind {
- Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA
- };
- enum {
- IsNestedCapture = 0x1,
- IsThisCaptured = 0x2
- };
- /// The variable being captured (if we are not capturing 'this') and whether
- /// this is a nested capture, and whether we are capturing 'this'
- llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis;
- /// Expression to initialize a field of the given type, and the kind of
- /// capture (if this is a capture and not an init-capture). The expression
- /// is only required if we are capturing ByVal and the variable's type has
- /// a non-trivial copy constructor.
- llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind;
-
- /// \brief The source location at which the first capture occurred.
- SourceLocation Loc;
+ bool isThisCapture() const {
+ return VarAndNestedAndThis.getInt() & IsThisCaptured;
+ }
- /// \brief The location of the ellipsis that expands a parameter pack.
- SourceLocation EllipsisLoc;
+ bool isVariableCapture() const {
+ return !isThisCapture() && !isVLATypeCapture();
+ }
- /// \brief The type as it was captured, which is in effect the type of the
- /// non-static data member that would hold the capture.
- QualType CaptureType;
+ bool isCopyCapture() const {
+ return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
+ }
- /// \brief Whether an explicit capture has been odr-used in the body of the
- /// lambda.
- bool ODRUsed;
+ bool isReferenceCapture() const {
+ return InitExprAndCaptureKind.getInt() == Cap_ByRef;
+ }
- /// \brief Whether an explicit capture has been non-odr-used in the body of
- /// the lambda.
- bool NonODRUsed;
+ bool isBlockCapture() const {
+ return InitExprAndCaptureKind.getInt() == Cap_Block;
+ }
- public:
- Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
- SourceLocation Loc, SourceLocation EllipsisLoc,
- QualType CaptureType, Expr *Cpy)
- : VarAndNestedAndThis(Var, IsNested ? IsNestedCapture : 0),
- InitExprAndCaptureKind(
- Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef
- : Cap_ByCopy),
- Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType),
- ODRUsed(false), NonODRUsed(false) {}
-
- enum IsThisCapture { ThisCapture };
- Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
- QualType CaptureType, Expr *Cpy, const bool ByCopy)
- : VarAndNestedAndThis(
- nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))),
- InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef),
- Loc(Loc), EllipsisLoc(), CaptureType(CaptureType), ODRUsed(false),
- NonODRUsed(false) {}
-
- bool isThisCapture() const {
- return VarAndNestedAndThis.getInt() & IsThisCaptured;
- }
- bool isVariableCapture() const {
- return !isThisCapture() && !isVLATypeCapture();
- }
- bool isCopyCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
- }
- bool isReferenceCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_ByRef;
- }
- bool isBlockCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_Block;
- }
- bool isVLATypeCapture() const {
- return InitExprAndCaptureKind.getInt() == Cap_VLA;
- }
- bool isNested() const {
- return VarAndNestedAndThis.getInt() & IsNestedCapture;
- }
- bool isODRUsed() const { return ODRUsed; }
- bool isNonODRUsed() const { return NonODRUsed; }
- void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; }
+ bool isVLATypeCapture() const {
+ return InitExprAndCaptureKind.getInt() == Cap_VLA;
+ }
- VarDecl *getVariable() const {
- assert(isVariableCapture());
- return VarAndNestedAndThis.getPointer();
- }
-
- /// \brief Retrieve the location at which this variable was captured.
- SourceLocation getLocation() const { return Loc; }
-
- /// \brief Retrieve the source location of the ellipsis, whose presence
- /// indicates that the capture is a pack expansion.
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
-
- /// \brief Retrieve the capture type for this capture, which is effectively
- /// the type of the non-static data member in the lambda/block structure
- /// that would store this capture.
- QualType getCaptureType() const {
- assert(!isThisCapture());
- return CaptureType;
- }
+ bool isNested() const {
+ return VarAndNestedAndThis.getInt() & IsNestedCapture;
+ }
- Expr *getInitExpr() const {
- assert(!isVLATypeCapture() && "no init expression for type capture");
- return static_cast<Expr *>(InitExprAndCaptureKind.getPointer());
- }
+ bool isODRUsed() const { return ODRUsed; }
+ bool isNonODRUsed() const { return NonODRUsed; }
+ void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; }
+
+ VarDecl *getVariable() const {
+ assert(isVariableCapture());
+ return VarAndNestedAndThis.getPointer();
+ }
+
+ /// Retrieve the location at which this variable was captured.
+ SourceLocation getLocation() const { return Loc; }
+
+ /// Retrieve the source location of the ellipsis, whose presence
+ /// indicates that the capture is a pack expansion.
+ SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+
+ /// Retrieve the capture type for this capture, which is effectively
+ /// the type of the non-static data member in the lambda/block structure
+ /// that would store this capture.
+ QualType getCaptureType() const {
+ assert(!isThisCapture());
+ return CaptureType;
+ }
+
+ Expr *getInitExpr() const {
+ assert(!isVLATypeCapture() && "no init expression for type capture");
+ return static_cast<Expr *>(InitExprAndCaptureKind.getPointer());
+ }
+};
+
+class CapturingScopeInfo : public FunctionScopeInfo {
+protected:
+ CapturingScopeInfo(const CapturingScopeInfo&) = default;
+
+public:
+ enum ImplicitCaptureStyle {
+ ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
+ ImpCap_CapturedRegion
};
+ ImplicitCaptureStyle ImpCaptureStyle;
+
CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
- : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
- HasImplicitReturnType(false)
- {}
+ : FunctionScopeInfo(Diag), ImpCaptureStyle(Style) {}
/// CaptureMap - A map of captured variables to (index+1) into Captures.
llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
/// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
/// zero if 'this' is not captured.
- unsigned CXXThisCaptureIndex;
+ unsigned CXXThisCaptureIndex = 0;
/// Captures - The captures.
SmallVector<Capture, 4> Captures;
- /// \brief - Whether the target type of return statements in this context
+ /// - Whether the target type of return statements in this context
/// is deduced (e.g. a lambda or block with omitted return type).
- bool HasImplicitReturnType;
+ bool HasImplicitReturnType = false;
/// ReturnType - The target type of return statements in this context,
/// or null if unknown.
@@ -629,24 +653,24 @@ public:
void addThisCapture(bool isNested, SourceLocation Loc,
Expr *Cpy, bool ByCopy);
- /// \brief Determine whether the C++ 'this' is captured.
+ /// Determine whether the C++ 'this' is captured.
bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
- /// \brief Retrieve the capture of C++ 'this', if it has been captured.
+ /// Retrieve the capture of C++ 'this', if it has been captured.
Capture &getCXXThisCapture() {
assert(isCXXThisCaptured() && "this has not been captured");
return Captures[CXXThisCaptureIndex - 1];
}
- /// \brief Determine whether the given variable has been captured.
+ /// Determine whether the given variable has been captured.
bool isCaptured(VarDecl *Var) const {
return CaptureMap.count(Var);
}
- /// \brief Determine whether the given variable-array type has been captured.
+ /// Determine whether the given variable-array type has been captured.
bool isVLATypeCaptured(const VariableArrayType *VAT) const;
- /// \brief Retrieve the capture of the given variable, if it has been
+ /// Retrieve the capture of the given variable, if it has been
/// captured already.
Capture &getCapture(VarDecl *Var) {
assert(isCaptured(Var) && "Variable has not been captured");
@@ -666,7 +690,7 @@ public:
}
};
-/// \brief Retains information about a block that is currently being parsed.
+/// Retains information about a block that is currently being parsed.
class BlockScopeInfo final : public CapturingScopeInfo {
public:
BlockDecl *TheDecl;
@@ -680,9 +704,8 @@ public:
QualType FunctionType;
BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
- : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
- TheScope(BlockScope)
- {
+ : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
+ TheScope(BlockScope) {
Kind = SK_Block;
}
@@ -693,38 +716,44 @@ public:
}
};
-/// \brief Retains information about a captured region.
+/// Retains information about a captured region.
class CapturedRegionScopeInfo final : public CapturingScopeInfo {
public:
- /// \brief The CapturedDecl for this statement.
+ /// The CapturedDecl for this statement.
CapturedDecl *TheCapturedDecl;
- /// \brief The captured record type.
+
+ /// The captured record type.
RecordDecl *TheRecordDecl;
- /// \brief This is the enclosing scope of the captured region.
+
+ /// This is the enclosing scope of the captured region.
Scope *TheScope;
- /// \brief The implicit parameter for the captured variables.
+
+ /// The implicit parameter for the captured variables.
ImplicitParamDecl *ContextParam;
- /// \brief The kind of captured region.
+
+ /// The kind of captured region.
unsigned short CapRegionKind;
+
unsigned short OpenMPLevel;
CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
RecordDecl *RD, ImplicitParamDecl *Context,
CapturedRegionKind K, unsigned OpenMPLevel)
- : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
- TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
- ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel)
- {
+ : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
+ TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
+ ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel) {
Kind = SK_CapturedRegion;
}
~CapturedRegionScopeInfo() override;
- /// \brief A descriptive name for the kind of captured region this is.
+ /// A descriptive name for the kind of captured region this is.
StringRef getRegionName() const {
switch (CapRegionKind) {
case CR_Default:
return "default captured statement";
+ case CR_ObjCAtFinally:
+ return "Objective-C @finally statement";
case CR_OpenMP:
return "OpenMP region";
}
@@ -738,40 +767,40 @@ public:
class LambdaScopeInfo final : public CapturingScopeInfo {
public:
- /// \brief The class that describes the lambda.
- CXXRecordDecl *Lambda;
+ /// The class that describes the lambda.
+ CXXRecordDecl *Lambda = nullptr;
- /// \brief The lambda's compiler-generated \c operator().
- CXXMethodDecl *CallOperator;
+ /// The lambda's compiler-generated \c operator().
+ CXXMethodDecl *CallOperator = nullptr;
- /// \brief Source range covering the lambda introducer [...].
+ /// Source range covering the lambda introducer [...].
SourceRange IntroducerRange;
- /// \brief Source location of the '&' or '=' specifying the default capture
+ /// Source location of the '&' or '=' specifying the default capture
/// type, if any.
SourceLocation CaptureDefaultLoc;
- /// \brief The number of captures in the \c Captures list that are
+ /// The number of captures in the \c Captures list that are
/// explicit captures.
- unsigned NumExplicitCaptures;
+ unsigned NumExplicitCaptures = 0;
- /// \brief Whether this is a mutable lambda.
- bool Mutable;
+ /// Whether this is a mutable lambda.
+ bool Mutable = false;
- /// \brief Whether the (empty) parameter list is explicit.
- bool ExplicitParams;
+ /// Whether the (empty) parameter list is explicit.
+ bool ExplicitParams = false;
- /// \brief Whether any of the capture expressions requires cleanups.
+ /// Whether any of the capture expressions requires cleanups.
CleanupInfo Cleanup;
- /// \brief Whether the lambda contains an unexpanded parameter pack.
- bool ContainsUnexpandedParameterPack;
+ /// Whether the lambda contains an unexpanded parameter pack.
+ bool ContainsUnexpandedParameterPack = false;
- /// \brief If this is a generic lambda, use this as the depth of
+ /// If this is a generic lambda, use this as the depth of
/// each 'auto' parameter, during initial AST construction.
- unsigned AutoTemplateParameterDepth;
+ unsigned AutoTemplateParameterDepth = 0;
- /// \brief Store the list of the auto parameters for a generic lambda.
+ /// Store the list of the auto parameters for a generic lambda.
/// If this is a generic lambda, store the list of the auto
/// parameters converted into TemplateTypeParmDecls into a vector
/// that can be used to construct the generic lambda's template
@@ -781,30 +810,32 @@ public:
/// If this is a generic lambda, and the template parameter
/// list has been created (from the AutoTemplateParams) then
/// store a reference to it (cache it to avoid reconstructing it).
- TemplateParameterList *GLTemplateParameterList;
+ TemplateParameterList *GLTemplateParameterList = nullptr;
- /// \brief Contains all variable-referring-expressions (i.e. DeclRefExprs
+ /// Contains all variable-referring-expressions (i.e. DeclRefExprs
/// or MemberExprs) that refer to local variables in a generic lambda
/// or a lambda in a potentially-evaluated-if-used context.
///
/// Potentially capturable variables of a nested lambda that might need
/// to be captured by the lambda are housed here.
/// This is specifically useful for generic lambdas or
- /// lambdas within a a potentially evaluated-if-used context.
+ /// lambdas within a potentially evaluated-if-used context.
/// If an enclosing variable is named in an expression of a lambda nested
/// within a generic lambda, we don't always know know whether the variable
/// will truly be odr-used (i.e. need to be captured) by that nested lambda,
/// until its instantiation. But we still need to capture it in the
/// enclosing lambda if all intervening lambdas can capture the variable.
-
llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs;
- /// \brief Contains all variable-referring-expressions that refer
+ /// Contains all variable-referring-expressions that refer
/// to local variables that are usable as constant expressions and
/// do not involve an odr-use (they may still need to be captured
/// if the enclosing full-expression is instantiation dependent).
llvm::SmallSet<Expr *, 8> NonODRUsedCapturingExprs;
+ /// A map of explicit capture indices to their introducer source ranges.
+ llvm::DenseMap<unsigned, SourceRange> ExplicitCaptureRanges;
+
/// Contains all of the variables defined in this lambda that shadow variables
/// that were defined in parent contexts. Used to avoid warnings when the
/// shadowed variables are uncaptured by this lambda.
@@ -817,15 +848,11 @@ public:
SourceLocation PotentialThisCaptureLocation;
LambdaScopeInfo(DiagnosticsEngine &Diag)
- : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr),
- CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false),
- ExplicitParams(false), Cleanup{},
- ContainsUnexpandedParameterPack(false), AutoTemplateParameterDepth(0),
- GLTemplateParameterList(nullptr) {
+ : CapturingScopeInfo(Diag, ImpCap_None) {
Kind = SK_Lambda;
}
- /// \brief Note when all explicit captures have been added.
+ /// Note when all explicit captures have been added.
void finishedExplicitCaptures() {
NumExplicitCaptures = Captures.size();
}
@@ -840,8 +867,7 @@ public:
return !AutoTemplateParams.empty() || GLTemplateParameterList;
}
- ///
- /// \brief Add a variable that might potentially be captured by the
+ /// Add a variable that might potentially be captured by the
/// lambda and therefore the enclosing lambdas.
///
/// This is also used by enclosing lambda's to speculatively capture
@@ -866,11 +892,12 @@ public:
void addPotentialThisCapture(SourceLocation Loc) {
PotentialThisCaptureLocation = Loc;
}
+
bool hasPotentialThisCapture() const {
return PotentialThisCaptureLocation.isValid();
}
- /// \brief Mark a variable's reference in a lambda as non-odr using.
+ /// Mark a variable's reference in a lambda as non-odr using.
///
/// For generic lambdas, if a variable is named in a potentially evaluated
/// expression, where the enclosing full expression is dependent then we
@@ -909,7 +936,6 @@ public:
/// seemingly harmless change elsewhere in Sema could cause us to start or stop
/// building such a node. So we need a rule that anyone can implement and get
/// exactly the same result".
- ///
void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
assert(isa<DeclRefExpr>(CapturingVarExpr)
|| isa<MemberExpr>(CapturingVarExpr));
@@ -945,7 +971,7 @@ public:
};
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
- : Base(nullptr, false), Property(nullptr) {}
+ : Base(nullptr, false) {}
FunctionScopeInfo::WeakObjectProfileTy
FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
@@ -970,7 +996,8 @@ CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
CXXThisCaptureIndex = Captures.size();
}
-} // end namespace sema
-} // end namespace clang
+} // namespace sema
+
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SEMA_SCOPEINFO_H
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 9cbe8e5cd63ef..b1077c620f8aa 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -17,9 +17,11 @@
#include "clang/AST/Attr.h"
#include "clang/AST/Availability.h"
-#include "clang/AST/DeclarationName.h"
+#include "clang/AST/ComparisonCategories.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/LocInfoType.h"
@@ -30,7 +32,6 @@
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeOrdering.h"
#include "clang/Basic/ExpressionTraits.h"
-#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/PragmaKinds.h"
@@ -45,12 +46,12 @@
#include "clang/Sema/ObjCMethodList.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Scope.h"
-#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/TypoCorrection.h"
#include "clang/Sema/Weak.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/TinyPtrVector.h"
@@ -75,7 +76,7 @@ namespace clang {
class ASTReader;
class ASTWriter;
class ArrayType;
- class AttributeList;
+ class ParsedAttr;
class BindingDecl;
class BlockDecl;
class CapturedDecl;
@@ -172,6 +173,7 @@ namespace clang {
class TemplateArgumentList;
class TemplateArgumentLoc;
class TemplateDecl;
+ class TemplateInstantiationCallback;
class TemplateParameterList;
class TemplatePartialOrderingContext;
class TemplateTemplateParmDecl;
@@ -200,6 +202,7 @@ namespace clang {
namespace sema {
class AccessedEntity;
class BlockScopeInfo;
+ class Capture;
class CapturedRegionScopeInfo;
class CapturingScopeInfo;
class CompoundScopeInfo;
@@ -275,10 +278,10 @@ class Sema {
Sema(const Sema &) = delete;
void operator=(const Sema &) = delete;
- ///\brief Source of additional semantic information.
+ ///Source of additional semantic information.
ExternalSemaSource *ExternalSource;
- ///\brief Whether Sema has generated a multiplexer and has to delete it.
+ ///Whether Sema has generated a multiplexer and has to delete it.
bool isMultiplexExternalSource;
static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD);
@@ -318,16 +321,16 @@ public:
DiagnosticsEngine &Diags;
SourceManager &SourceMgr;
- /// \brief Flag indicating whether or not to collect detailed statistics.
+ /// Flag indicating whether or not to collect detailed statistics.
bool CollectStats;
- /// \brief Code-completion consumer.
+ /// Code-completion consumer.
CodeCompleteConsumer *CodeCompleter;
/// CurContext - This is the current declaration context of parsing.
DeclContext *CurContext;
- /// \brief Generally null except when we temporarily switch decl contexts,
+ /// Generally null except when we temporarily switch decl contexts,
/// like in \see ActOnObjCTemporaryExitContainerContext.
DeclContext *OriginalLexicalContext;
@@ -337,17 +340,17 @@ public:
bool MSStructPragmaOn; // True when \#pragma ms_struct on
- /// \brief Controls member pointer representation format under the MS ABI.
+ /// Controls member pointer representation format under the MS ABI.
LangOptions::PragmaMSPointersToMembersKind
MSPointerToMemberRepresentationMethod;
/// Stack of active SEH __finally scopes. Can be empty.
SmallVector<Scope*, 2> CurrentSEHFinally;
- /// \brief Source location for newly created implicit MSInheritanceAttrs
+ /// Source location for newly created implicit MSInheritanceAttrs
SourceLocation ImplicitMSInheritanceAttrLoc;
- /// \brief pragma clang section kind
+ /// pragma clang section kind
enum PragmaClangSectionKind {
PCSK_Invalid = 0,
PCSK_BSS = 1,
@@ -438,7 +441,7 @@ public:
// FIXME: We should serialize / deserialize these if they occur in a PCH (but
// we shouldn't do so if they're in a module).
- /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft
+ /// Whether to insert vtordisps prior to virtual bases in the Microsoft
/// C++ ABI. Possible values are 0, 1, and 2, which mean:
///
/// 0: Suppress all vtordisps
@@ -487,26 +490,26 @@ public:
/// VisContext - Manages the stack for \#pragma GCC visibility.
void *VisContext; // Really a "PragmaVisStack*"
- /// \brief This represents the stack of attributes that were pushed by
+ /// This represents the stack of attributes that were pushed by
/// \#pragma clang attribute.
struct PragmaAttributeEntry {
SourceLocation Loc;
- AttributeList *Attribute;
+ ParsedAttr *Attribute;
SmallVector<attr::SubjectMatchRule, 4> MatchRules;
bool IsUsed;
};
SmallVector<PragmaAttributeEntry, 2> PragmaAttributeStack;
- /// \brief The declaration that is currently receiving an attribute from the
+ /// The declaration that is currently receiving an attribute from the
/// #pragma attribute stack.
const Decl *PragmaAttributeCurrentTargetDecl;
- /// \brief This represents the last location of a "#pragma clang optimize off"
+ /// This represents the last location of a "#pragma clang optimize off"
/// directive if such a directive has not been closed by an "on" yet. If
/// optimizations are currently "on", this is set to an invalid location.
SourceLocation OptimizeOffPragmaLocation;
- /// \brief Flag indicating if Sema is building a recovery call expression.
+ /// Flag indicating if Sema is building a recovery call expression.
///
/// This flag is used to avoid building recovery call expressions
/// if Sema is already doing so, which would cause infinite recursions.
@@ -520,7 +523,7 @@ public:
/// element type here is ExprWithCleanups::Object.
SmallVector<BlockDecl*, 8> ExprCleanupObjects;
- /// \brief Store a list of either DeclRefExprs or MemberExprs
+ /// Store a list of either DeclRefExprs or MemberExprs
/// that contain a reference to a variable (constant) that may or may not
/// be odr-used in this Expr, and we won't know until all lvalue-to-rvalue
/// and discarded value conversions have been applied to all subexpressions
@@ -528,12 +531,10 @@ public:
/// full expression.
llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs;
- /// \brief Stack containing information about each of the nested
+ std::unique_ptr<sema::FunctionScopeInfo> PreallocatedFunctionScope;
+
+ /// Stack containing information about each of the nested
/// function, block, and method scopes that are currently active.
- ///
- /// This array is never empty. Clients should ignore the first
- /// element, which is used to cache a single FunctionScopeInfo
- /// that's used to parse every top-level function.
SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes;
typedef LazyVector<TypedefNameDecl *, ExternalSemaSource,
@@ -548,16 +549,16 @@ public:
/// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
std::unique_ptr<CXXFieldCollector> FieldCollector;
- typedef llvm::SmallSetVector<const NamedDecl*, 16> NamedDeclSetType;
+ typedef llvm::SmallSetVector<NamedDecl *, 16> NamedDeclSetType;
- /// \brief Set containing all declared private fields that are not used.
+ /// Set containing all declared private fields that are not used.
NamedDeclSetType UnusedPrivateFields;
- /// \brief Set containing all typedefs that are likely unused.
+ /// Set containing all typedefs that are likely unused.
llvm::SmallSetVector<const TypedefNameDecl *, 4>
UnusedLocalTypedefNameCandidates;
- /// \brief Delete-expressions to be analyzed at the end of translation unit
+ /// Delete-expressions to be analyzed at the end of translation unit
///
/// This list contains class members, and locations of delete-expressions
/// that could not be proven as to whether they mismatch with new-expression
@@ -577,21 +578,21 @@ public:
/// we are currently parsing the initializer.
llvm::SmallPtrSet<const Decl*, 4> ParsingInitForAutoVars;
- /// \brief Look for a locally scoped extern "C" declaration by the given name.
+ /// Look for a locally scoped extern "C" declaration by the given name.
NamedDecl *findLocallyScopedExternCDecl(DeclarationName Name);
typedef LazyVector<VarDecl *, ExternalSemaSource,
&ExternalSemaSource::ReadTentativeDefinitions, 2, 2>
TentativeDefinitionsType;
- /// \brief All the tentative definitions encountered in the TU.
+ /// All the tentative definitions encountered in the TU.
TentativeDefinitionsType TentativeDefinitions;
typedef LazyVector<const DeclaratorDecl *, ExternalSemaSource,
&ExternalSemaSource::ReadUnusedFileScopedDecls, 2, 2>
UnusedFileScopedDeclsType;
- /// \brief The set of file scoped decls seen so far that have not been used
+ /// The set of file scoped decls seen so far that have not been used
/// and must warn if not used. Only contains the first declaration.
UnusedFileScopedDeclsType UnusedFileScopedDecls;
@@ -599,17 +600,17 @@ public:
&ExternalSemaSource::ReadDelegatingConstructors, 2, 2>
DelegatingCtorDeclsType;
- /// \brief All the delegating constructors seen so far in the file, used for
+ /// All the delegating constructors seen so far in the file, used for
/// cycle detection at the end of the TU.
DelegatingCtorDeclsType DelegatingCtorDecls;
- /// \brief All the overriding functions seen during a class definition
+ /// All the overriding functions seen during a class definition
/// that had their exception spec checks delayed, plus the overridden
/// function.
SmallVector<std::pair<const CXXMethodDecl*, const CXXMethodDecl*>, 2>
DelayedExceptionSpecChecks;
- /// \brief All the members seen during a class definition which were both
+ /// All the members seen during a class definition which were both
/// explicitly defaulted and had explicitly-specified exception
/// specifications, along with the function type containing their
/// user-specified exception specification. Those exception specifications
@@ -624,7 +625,7 @@ public:
LateParsedTemplateMapT;
LateParsedTemplateMapT LateParsedTemplateMap;
- /// \brief Callback to the parser to parse templated functions when needed.
+ /// Callback to the parser to parse templated functions when needed.
typedef void LateTemplateParserCB(void *P, LateParsedTemplate &LPT);
typedef void LateTemplateParserCleanupCB(void *P);
LateTemplateParserCB *LateTemplateParser;
@@ -651,7 +652,7 @@ public:
/// A class which encapsulates the logic for delaying diagnostics
/// during parsing and other processing.
class DelayedDiagnostics {
- /// \brief The current pool of diagnostics into which delayed
+ /// The current pool of diagnostics into which delayed
/// diagnostics should go.
sema::DelayedDiagnosticPool *CurPool;
@@ -734,7 +735,7 @@ public:
}
};
- /// \brief RAII object to handle the state changes required to synthesize
+ /// RAII object to handle the state changes required to synthesize
/// a function body.
class SynthesizedFunctionScope {
Sema &S;
@@ -787,7 +788,7 @@ public:
llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*> ExtnameUndeclaredIdentifiers;
- /// \brief Load weak undeclared identifiers from the external source.
+ /// Load weak undeclared identifiers from the external source.
void LoadExternalWeakUndeclaredIdentifiers();
/// WeakTopLevelDecl - Translation-unit scoped declarations generated by
@@ -804,77 +805,81 @@ public:
/// For example, user-defined classes, built-in "id" type, etc.
Scope *TUScope;
- /// \brief The C++ "std" namespace, where the standard library resides.
+ /// The C++ "std" namespace, where the standard library resides.
LazyDeclPtr StdNamespace;
- /// \brief The C++ "std::bad_alloc" class, which is defined by the C++
+ /// The C++ "std::bad_alloc" class, which is defined by the C++
/// standard library.
LazyDeclPtr StdBadAlloc;
- /// \brief The C++ "std::align_val_t" enum class, which is defined by the C++
+ /// The C++ "std::align_val_t" enum class, which is defined by the C++
/// standard library.
LazyDeclPtr StdAlignValT;
- /// \brief The C++ "std::experimental" namespace, where the experimental parts
+ /// The C++ "std::experimental" namespace, where the experimental parts
/// of the standard library resides.
NamespaceDecl *StdExperimentalNamespaceCache;
- /// \brief The C++ "std::initializer_list" template, which is defined in
+ /// The C++ "std::initializer_list" template, which is defined in
/// \<initializer_list>.
ClassTemplateDecl *StdInitializerList;
- /// \brief The C++ "type_info" declaration, which is defined in \<typeinfo>.
+ /// The C++ "std::coroutine_traits" template, which is defined in
+ /// \<coroutine_traits>
+ ClassTemplateDecl *StdCoroutineTraitsCache;
+
+ /// The C++ "type_info" declaration, which is defined in \<typeinfo>.
RecordDecl *CXXTypeInfoDecl;
- /// \brief The MSVC "_GUID" struct, which is defined in MSVC header files.
+ /// The MSVC "_GUID" struct, which is defined in MSVC header files.
RecordDecl *MSVCGuidDecl;
- /// \brief Caches identifiers/selectors for NSFoundation APIs.
+ /// Caches identifiers/selectors for NSFoundation APIs.
std::unique_ptr<NSAPI> NSAPIObj;
- /// \brief The declaration of the Objective-C NSNumber class.
+ /// The declaration of the Objective-C NSNumber class.
ObjCInterfaceDecl *NSNumberDecl;
- /// \brief The declaration of the Objective-C NSValue class.
+ /// The declaration of the Objective-C NSValue class.
ObjCInterfaceDecl *NSValueDecl;
- /// \brief Pointer to NSNumber type (NSNumber *).
+ /// Pointer to NSNumber type (NSNumber *).
QualType NSNumberPointer;
- /// \brief Pointer to NSValue type (NSValue *).
+ /// Pointer to NSValue type (NSValue *).
QualType NSValuePointer;
- /// \brief The Objective-C NSNumber methods used to create NSNumber literals.
+ /// The Objective-C NSNumber methods used to create NSNumber literals.
ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods];
- /// \brief The declaration of the Objective-C NSString class.
+ /// The declaration of the Objective-C NSString class.
ObjCInterfaceDecl *NSStringDecl;
- /// \brief Pointer to NSString type (NSString *).
+ /// Pointer to NSString type (NSString *).
QualType NSStringPointer;
- /// \brief The declaration of the stringWithUTF8String: method.
+ /// The declaration of the stringWithUTF8String: method.
ObjCMethodDecl *StringWithUTF8StringMethod;
- /// \brief The declaration of the valueWithBytes:objCType: method.
+ /// The declaration of the valueWithBytes:objCType: method.
ObjCMethodDecl *ValueWithBytesObjCTypeMethod;
- /// \brief The declaration of the Objective-C NSArray class.
+ /// The declaration of the Objective-C NSArray class.
ObjCInterfaceDecl *NSArrayDecl;
- /// \brief The declaration of the arrayWithObjects:count: method.
+ /// The declaration of the arrayWithObjects:count: method.
ObjCMethodDecl *ArrayWithObjectsMethod;
- /// \brief The declaration of the Objective-C NSDictionary class.
+ /// The declaration of the Objective-C NSDictionary class.
ObjCInterfaceDecl *NSDictionaryDecl;
- /// \brief The declaration of the dictionaryWithObjects:forKeys:count: method.
+ /// The declaration of the dictionaryWithObjects:forKeys:count: method.
ObjCMethodDecl *DictionaryWithObjectsMethod;
- /// \brief id<NSCopying> type.
+ /// id<NSCopying> type.
QualType QIDNSCopying;
- /// \brief will hold 'respondsToSelector:'
+ /// will hold 'respondsToSelector:'
Selector RespondsToSelectorSel;
/// A flag to remember whether the implicit forms of operator new and delete
@@ -885,43 +890,43 @@ public:
/// references to fields. This is really a
bool AllowAbstractFieldReference;
- /// \brief Describes how the expressions currently being parsed are
+ /// Describes how the expressions currently being parsed are
/// evaluated at run-time, if at all.
enum class ExpressionEvaluationContext {
- /// \brief The current expression and its subexpressions occur within an
+ /// The current expression and its subexpressions occur within an
/// unevaluated operand (C++11 [expr]p7), such as the subexpression of
/// \c sizeof, where the type of the expression may be significant but
/// no code will be generated to evaluate the value of the expression at
/// run time.
Unevaluated,
- /// \brief The current expression occurs within a braced-init-list within
+ /// The current expression occurs within a braced-init-list within
/// an unevaluated operand. This is mostly like a regular unevaluated
/// context, except that we still instantiate constexpr functions that are
/// referenced here so that we can perform narrowing checks correctly.
UnevaluatedList,
- /// \brief The current expression occurs within a discarded statement.
+ /// The current expression occurs within a discarded statement.
/// This behaves largely similarly to an unevaluated operand in preventing
/// definitions from being required, but not in other ways.
DiscardedStatement,
- /// \brief The current expression occurs within an unevaluated
+ /// The current expression occurs within an unevaluated
/// operand that unconditionally permits abstract references to
/// fields, such as a SIZE operator in MS-style inline assembly.
UnevaluatedAbstract,
- /// \brief The current context is "potentially evaluated" in C++11 terms,
+ /// The current context is "potentially evaluated" in C++11 terms,
/// but the expression is evaluated at compile-time (like the values of
/// cases in a switch statement).
ConstantEvaluated,
- /// \brief The current expression is potentially evaluated at run time,
+ /// The current expression is potentially evaluated at run time,
/// which means that code may be generated to evaluate the value of the
/// expression at run time.
PotentiallyEvaluated,
- /// \brief The current expression is potentially evaluated, but any
+ /// The current expression is potentially evaluated, but any
/// declarations referenced inside that expression are only used if
/// in fact the current expression is used.
///
@@ -932,63 +937,69 @@ public:
PotentiallyEvaluatedIfUsed
};
- /// \brief Data structure used to record current or nested
+ /// Data structure used to record current or nested
/// expression evaluation contexts.
struct ExpressionEvaluationContextRecord {
- /// \brief The expression evaluation context.
+ /// The expression evaluation context.
ExpressionEvaluationContext Context;
- /// \brief Whether the enclosing context needed a cleanup.
+ /// Whether the enclosing context needed a cleanup.
CleanupInfo ParentCleanup;
- /// \brief Whether we are in a decltype expression.
+ /// Whether we are in a decltype expression.
bool IsDecltype;
- /// \brief The number of active cleanup objects when we entered
+ /// The number of active cleanup objects when we entered
/// this expression evaluation context.
unsigned NumCleanupObjects;
- /// \brief The number of typos encountered during this expression evaluation
+ /// The number of typos encountered during this expression evaluation
/// context (i.e. the number of TypoExprs created).
unsigned NumTypos;
llvm::SmallPtrSet<Expr*, 2> SavedMaybeODRUseExprs;
- /// \brief The lambdas that are present within this context, if it
+ /// The lambdas that are present within this context, if it
/// is indeed an unevaluated context.
SmallVector<LambdaExpr *, 2> Lambdas;
- /// \brief The declaration that provides context for lambda expressions
+ /// The declaration that provides context for lambda expressions
/// and block literals if the normal declaration context does not
/// suffice, e.g., in a default function argument.
Decl *ManglingContextDecl;
- /// \brief The context information used to mangle lambda expressions
+ /// The context information used to mangle lambda expressions
/// and block literals within this context.
///
/// This mangling information is allocated lazily, since most contexts
/// do not have lambda expressions or block literals.
std::unique_ptr<MangleNumberingContext> MangleNumbering;
- /// \brief If we are processing a decltype type, a set of call expressions
+ /// If we are processing a decltype type, a set of call expressions
/// for which we have deferred checking the completeness of the return type.
SmallVector<CallExpr *, 8> DelayedDecltypeCalls;
- /// \brief If we are processing a decltype type, a set of temporary binding
+ /// If we are processing a decltype type, a set of temporary binding
/// expressions for which we have deferred checking the destructor.
SmallVector<CXXBindTemporaryExpr *, 8> DelayedDecltypeBinds;
+ /// \brief Describes whether we are in an expression constext which we have
+ /// to handle differently.
+ enum ExpressionKind {
+ EK_Decltype, EK_TemplateArgument, EK_Other
+ } ExprContext;
+
ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
unsigned NumCleanupObjects,
CleanupInfo ParentCleanup,
Decl *ManglingContextDecl,
- bool IsDecltype)
- : Context(Context), ParentCleanup(ParentCleanup),
- IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects),
- NumTypos(0),
- ManglingContextDecl(ManglingContextDecl), MangleNumbering() { }
+ ExpressionKind ExprContext)
+ : Context(Context), ParentCleanup(ParentCleanup),
+ NumCleanupObjects(NumCleanupObjects), NumTypos(0),
+ ManglingContextDecl(ManglingContextDecl), MangleNumbering(),
+ ExprContext(ExprContext) {}
- /// \brief Retrieve the mangling numbering context, used to consistently
+ /// Retrieve the mangling numbering context, used to consistently
/// number constructs like lambdas for mangling.
MangleNumberingContext &getMangleNumberingContext(ASTContext &Ctx);
@@ -1005,7 +1016,7 @@ public:
/// A stack of expression evaluation contexts.
SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
- /// \brief Compute the mangling number context for a lambda expression or
+ /// Compute the mangling number context for a lambda expression or
/// block literal.
///
/// \param DC - The DeclContext containing the lambda expression or
@@ -1054,15 +1065,15 @@ public:
{}
};
- /// \brief A cache of special member function overload resolution results
+ /// A cache of special member function overload resolution results
/// for C++ records.
llvm::FoldingSet<SpecialMemberOverloadResultEntry> SpecialMemberCache;
- /// \brief A cache of the flags available in enumerations with the flag_bits
+ /// A cache of the flags available in enumerations with the flag_bits
/// attribute.
mutable llvm::DenseMap<const EnumDecl*, llvm::APInt> FlagBitsCache;
- /// \brief The kind of translation unit we are processing.
+ /// The kind of translation unit we are processing.
///
/// When we're processing a complete translation unit, Sema will perform
/// end-of-translation-unit semantic tasks (such as creating
@@ -1073,13 +1084,13 @@ public:
llvm::BumpPtrAllocator BumpAlloc;
- /// \brief The number of SFINAE diagnostics that have been trapped.
+ /// The number of SFINAE diagnostics that have been trapped.
unsigned NumSFINAEErrors;
typedef llvm::DenseMap<ParmVarDecl *, llvm::TinyPtrVector<ParmVarDecl *>>
UnparsedDefaultArgInstantiationsMap;
- /// \brief A mapping from parameters with unparsed default arguments to the
+ /// A mapping from parameters with unparsed default arguments to the
/// set of instantiations of each parameter.
///
/// This mapping is a temporary data structure used when parsing
@@ -1161,7 +1172,7 @@ public:
bool isSelfExpr(Expr *RExpr);
bool isSelfExpr(Expr *RExpr, const ObjCMethodDecl *Method);
- /// \brief Cause the active diagnostic on the DiagosticsEngine to be
+ /// Cause the active diagnostic on the DiagosticsEngine to be
/// emitted. This is closely coupled to the SemaDiagnosticBuilder class and
/// should not be used elsewhere.
void EmitCurrentDiagnostic(unsigned DiagID);
@@ -1186,7 +1197,7 @@ public:
CodeCompleteConsumer *CompletionConsumer = nullptr);
~Sema();
- /// \brief Perform initialization that occurs after the parser has been
+ /// Perform initialization that occurs after the parser has been
/// initialized but before it parses anything.
void Initialize();
@@ -1202,7 +1213,7 @@ public:
ASTMutationListener *getASTMutationListener() const;
ExternalSemaSource* getExternalSource() const { return ExternalSource; }
- ///\brief Registers an external source. If an external source already exists,
+ ///Registers an external source. If an external source already exists,
/// creates a multiplex external source and appends to it.
///
///\param[in] E - A non-null external sema source.
@@ -1211,7 +1222,7 @@ public:
void PrintStats() const;
- /// \brief Helper class that creates diagnostics with optional
+ /// Helper class that creates diagnostics with optional
/// template instantiation stacks.
///
/// This class provides a wrapper around the basic DiagnosticBuilder
@@ -1266,29 +1277,29 @@ public:
}
};
- /// \brief Emit a diagnostic.
+ /// Emit a diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
DiagnosticBuilder DB = Diags.Report(Loc, DiagID);
return SemaDiagnosticBuilder(DB, *this, DiagID);
}
- /// \brief Emit a partial diagnostic.
+ /// Emit a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD);
- /// \brief Build a partial diagnostic.
+ /// Build a partial diagnostic.
PartialDiagnostic PDiag(unsigned DiagID = 0); // in SemaInternal.h
bool findMacroSpelling(SourceLocation &loc, StringRef name);
- /// \brief Get a string to suggest for zero-initialization of a type.
+ /// Get a string to suggest for zero-initialization of a type.
std::string
getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const;
std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const;
- /// \brief Calls \c Lexer::getLocForEndOfToken()
+ /// Calls \c Lexer::getLocForEndOfToken()
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0);
- /// \brief Retrieve the module loader associated with the preprocessor.
+ /// Retrieve the module loader associated with the preprocessor.
ModuleLoader &getModuleLoader() const;
void emitAndClearUnusedLocalTypedefWarnings();
@@ -1304,7 +1315,7 @@ public:
void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
sema::LambdaScopeInfo *PushLambdaScope();
- /// \brief This is used to inform Sema what the current TemplateParameterDepth
+ /// This is used to inform Sema what the current TemplateParameterDepth
/// is during Parsing. Currently it is used to pass on the depth
/// when parsing generic lambda 'auto' parameters.
void RecordParsingTemplateParameterDepth(unsigned Depth);
@@ -1318,35 +1329,23 @@ public:
const BlockExpr *blkExpr = nullptr);
sema::FunctionScopeInfo *getCurFunction() const {
- return FunctionScopes.back();
+ return FunctionScopes.empty() ? nullptr : FunctionScopes.back();
}
- sema::FunctionScopeInfo *getEnclosingFunction() const {
- if (FunctionScopes.empty())
- return nullptr;
+ sema::FunctionScopeInfo *getEnclosingFunction() const;
- for (int e = FunctionScopes.size()-1; e >= 0; --e) {
- if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
- continue;
- return FunctionScopes[e];
- }
- return nullptr;
- }
+ void setFunctionHasBranchIntoScope();
+ void setFunctionHasBranchProtectedScope();
+ void setFunctionHasIndirectGoto();
- template <typename ExprT>
- void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) {
- if (!isUnevaluatedContext())
- getCurFunction()->recordUseOfWeak(E, IsRead);
- }
-
- void PushCompoundScope();
+ void PushCompoundScope(bool IsStmtExpr);
void PopCompoundScope();
sema::CompoundScopeInfo &getCurCompoundScope() const;
bool hasAnyUnrecoverableErrorsInThisFunction() const;
- /// \brief Retrieve the current block, if any.
+ /// Retrieve the current block, if any.
sema::BlockScopeInfo *getCurBlock();
/// Retrieve the current lambda scope info, if any.
@@ -1356,10 +1355,10 @@ public:
sema::LambdaScopeInfo *
getCurLambda(bool IgnoreNonLambdaCapturingScope = false);
- /// \brief Retrieve the current generic lambda info, if any.
+ /// Retrieve the current generic lambda info, if any.
sema::LambdaScopeInfo *getCurGenericLambda();
- /// \brief Retrieve the current captured region, if any.
+ /// Retrieve the current captured region, if any.
sema::CapturedRegionScopeInfo *getCurCapturedRegion();
/// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls
@@ -1382,6 +1381,7 @@ public:
QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
Expr *ArraySize, unsigned Quals,
SourceRange Brackets, DeclarationName Entity);
+ QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc);
QualType BuildExtVectorType(QualType T, Expr *ArraySize,
SourceLocation AttrLoc);
QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
@@ -1389,7 +1389,7 @@ public:
bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
- /// \brief Build a function type.
+ /// Build a function type.
///
/// This routine checks the function type according to C++ rules and
/// under the assumption that the result type and parameter types have
@@ -1438,7 +1438,7 @@ public:
TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
TypeSourceInfo *ReturnTypeInfo);
- /// \brief Package the given type and TSI into a ParsedType.
+ /// Package the given type and TSI into a ParsedType.
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo);
DeclarationNameInfo GetNameForDeclarator(Declarator &D);
DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name);
@@ -1459,6 +1459,7 @@ public:
const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
const FunctionProtoType *Old, SourceLocation OldLoc,
const FunctionProtoType *New, SourceLocation NewLoc);
+ bool handlerCanCatch(QualType HandlerType, QualType ExceptionType);
bool CheckExceptionSpecSubset(const PartialDiagnostic &DiagID,
const PartialDiagnostic &NestedDiagID,
const PartialDiagnostic &NoteID,
@@ -1475,11 +1476,11 @@ public:
TypeResult ActOnTypeName(Scope *S, Declarator &D);
- /// \brief The parser has parsed the context-sensitive type 'instancetype'
+ /// The parser has parsed the context-sensitive type 'instancetype'
/// in an Objective-C message declaration. Return the appropriate type.
ParsedType ActOnObjCInstanceType(SourceLocation Loc);
- /// \brief Abstract class used to diagnose incomplete types.
+ /// Abstract class used to diagnose incomplete types.
struct TypeDiagnoser {
TypeDiagnoser() {}
@@ -1548,10 +1549,10 @@ private:
VisibleModuleSet VisibleModules;
public:
- /// \brief Get the module owning an entity.
+ /// Get the module owning an entity.
Module *getOwningModule(Decl *Entity) { return Entity->getOwningModule(); }
- /// \brief Make a merged definition of an existing hidden definition \p ND
+ /// Make a merged definition of an existing hidden definition \p ND
/// visible at the specified location.
void makeMergedDefinitionVisible(NamedDecl *ND);
@@ -1649,7 +1650,8 @@ public:
}
QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
- const CXXScopeSpec &SS, QualType T);
+ const CXXScopeSpec &SS, QualType T,
+ TagDecl *OwnedTagDecl = nullptr);
QualType BuildTypeofExprType(Expr *E, SourceLocation Loc);
/// If AsUnevaluated is false, E is treated as though it were an evaluated
@@ -1705,7 +1707,7 @@ public:
SourceLocation NameLoc,
bool IsTemplateTypeArg);
- /// \brief Describes the result of the name lookup and resolution performed
+ /// Describes the result of the name lookup and resolution performed
/// by \c ClassifyName().
enum NameClassificationKind {
NC_Unknown,
@@ -1796,7 +1798,7 @@ public:
}
};
- /// \brief Perform name lookup on the given name, classifying it based on
+ /// Perform name lookup on the given name, classifying it based on
/// the results of name lookup and the following token.
///
/// This routine is used by the parser to resolve identifiers and help direct
@@ -1840,13 +1842,19 @@ public:
/// Determine whether it's plausible that E was intended to be a
/// template-name.
- bool mightBeIntendedToBeTemplateName(ExprResult E) {
+ bool mightBeIntendedToBeTemplateName(ExprResult E, bool &Dependent) {
if (!getLangOpts().CPlusPlus || E.isInvalid())
return false;
+ Dependent = false;
if (auto *DRE = dyn_cast<DeclRefExpr>(E.get()))
return !DRE->hasExplicitTemplateArgs();
if (auto *ME = dyn_cast<MemberExpr>(E.get()))
return !ME->hasExplicitTemplateArgs();
+ Dependent = true;
+ if (auto *DSDRE = dyn_cast<DependentScopeDeclRefExpr>(E.get()))
+ return !DSDRE->hasExplicitTemplateArgs();
+ if (auto *DSME = dyn_cast<CXXDependentScopeMemberExpr>(E.get()))
+ return !DSME->hasExplicitTemplateArgs();
// Any additional cases recognized here should also be handled by
// diagnoseExprIntendedAsTemplateName.
return false;
@@ -1862,8 +1870,8 @@ public:
void RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S);
bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
- DeclarationName Name,
- SourceLocation Loc);
+ DeclarationName Name, SourceLocation Loc,
+ bool IsTemplateId);
void
diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
SourceLocation FallbackLoc,
@@ -1944,6 +1952,7 @@ public:
bool shouldLinkDependentDeclWithPrevious(Decl *D, Decl *OldDecl);
void CheckMain(FunctionDecl *FD, const DeclSpec &D);
void CheckMSVCRTEntryPoint(FunctionDecl *FD);
+ Attr *getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, bool IsDefinition);
Decl *ActOnParamDeclarator(Scope *S, Declarator &D);
ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC,
SourceLocation Loc,
@@ -1999,7 +2008,7 @@ public:
return D && isa<ObjCMethodDecl>(D);
}
- /// \brief Determine whether we can delay parsing the body of a function or
+ /// Determine whether we can delay parsing the body of a function or
/// function template until it is used, assuming we don't care about emitting
/// code for that function.
///
@@ -2009,7 +2018,7 @@ public:
/// or has an 'auto' return type in C++14. These cases are essentially bugs.
bool canDelayFunctionBody(const Declarator &D);
- /// \brief Determine whether we can skip parsing the body of a function
+ /// Determine whether we can skip parsing the body of a function
/// definition, assuming we don't care about analyzing its body or emitting
/// code for that function.
///
@@ -2028,11 +2037,11 @@ public:
/// attribute for which parsing is delayed.
void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs);
- /// \brief Diagnose any unused parameters in the given sequence of
+ /// Diagnose any unused parameters in the given sequence of
/// ParmVarDecl pointers.
void DiagnoseUnusedParameters(ArrayRef<ParmVarDecl *> Parameters);
- /// \brief Diagnose whether the size of parameters or return value of a
+ /// Diagnose whether the size of parameters or return value of a
/// function or obj-c method definition is pass-by-value and larger than a
/// specified threshold.
void
@@ -2044,9 +2053,8 @@ public:
SourceLocation AsmLoc,
SourceLocation RParenLoc);
- /// \brief Handle a C++11 empty-declaration and attribute-declaration.
- Decl *ActOnEmptyDeclaration(Scope *S,
- AttributeList *AttrList,
+ /// Handle a C++11 empty-declaration and attribute-declaration.
+ Decl *ActOnEmptyDeclaration(Scope *S, const ParsedAttributesView &AttrList,
SourceLocation SemiLoc);
enum class ModuleDeclKind {
@@ -2061,7 +2069,7 @@ public:
SourceLocation ModuleLoc, ModuleDeclKind MDK,
ModuleIdPath Path);
- /// \brief The parser has processed a module import declaration.
+ /// The parser has processed a module import declaration.
///
/// \param AtLoc The location of the '@' symbol, if any.
///
@@ -2071,17 +2079,17 @@ public:
DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc,
ModuleIdPath Path);
- /// \brief The parser has processed a module import translated from a
+ /// The parser has processed a module import translated from a
/// #include or similar preprocessing directive.
void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
void BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
- /// \brief The parsed has entered a submodule.
+ /// The parsed has entered a submodule.
void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod);
- /// \brief The parser has left a submodule.
+ /// The parser has left a submodule.
void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod);
- /// \brief Create an implicit import of the given module at the given
+ /// Create an implicit import of the given module at the given
/// source location, for error recovery, if possible.
///
/// This routine is typically used when an entity found by name lookup
@@ -2100,7 +2108,7 @@ public:
PartialSpecialization
};
- /// \brief Diagnose that the specified declaration needs to be visible but
+ /// Diagnose that the specified declaration needs to be visible but
/// isn't, and suggest a module import that would resolve the problem.
void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl,
MissingImportKind MIK, bool Recover = true);
@@ -2113,23 +2121,23 @@ public:
Decl *ActOnFinishExportDecl(Scope *S, Decl *ExportDecl,
SourceLocation RBraceLoc);
- /// \brief We've found a use of a templated declaration that would trigger an
+ /// We've found a use of a templated declaration that would trigger an
/// implicit instantiation. Check that any relevant explicit specializations
/// and partial specializations are visible, and diagnose if not.
void checkSpecializationVisibility(SourceLocation Loc, NamedDecl *Spec);
- /// \brief We've found a use of a template specialization that would select a
+ /// We've found a use of a template specialization that would select a
/// partial specialization. Check that the partial specialization is visible,
/// and diagnose if not.
void checkPartialSpecializationVisibility(SourceLocation Loc,
NamedDecl *Spec);
- /// \brief Retrieve a suitable printing policy.
+ /// Retrieve a suitable printing policy for diagnostics.
PrintingPolicy getPrintingPolicy() const {
return getPrintingPolicy(Context, PP);
}
- /// \brief Retrieve a suitable printing policy.
+ /// Retrieve a suitable printing policy for diagnostics.
static PrintingPolicy getPrintingPolicy(const ASTContext &Ctx,
const Preprocessor &PP);
@@ -2184,7 +2192,7 @@ public:
Decl *ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name,
- SourceLocation NameLoc, AttributeList *Attr,
+ SourceLocation NameLoc, const ParsedAttributesView &Attr,
AccessSpecifier AS, SourceLocation ModulePrivateLoc,
MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl,
bool &IsDependent, SourceLocation ScopedEnumKWLoc,
@@ -2194,9 +2202,9 @@ public:
Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
unsigned TagSpec, SourceLocation TagLoc,
- CXXScopeSpec &SS,
- IdentifierInfo *Name, SourceLocation NameLoc,
- AttributeList *Attr,
+ CXXScopeSpec &SS, IdentifierInfo *Name,
+ SourceLocation NameLoc,
+ const ParsedAttributesView &Attr,
MultiTemplateParamsArg TempParamLists);
TypeResult ActOnDependentTag(Scope *S,
@@ -2218,11 +2226,11 @@ public:
InClassInitStyle InitStyle,
AccessSpecifier AS);
MSPropertyDecl *HandleMSProperty(Scope *S, RecordDecl *TagD,
- SourceLocation DeclStart,
- Declarator &D, Expr *BitfieldWidth,
+ SourceLocation DeclStart, Declarator &D,
+ Expr *BitfieldWidth,
InClassInitStyle InitStyle,
AccessSpecifier AS,
- AttributeList *MSPropertyAttr);
+ const ParsedAttr &MSPropertyAttr);
FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
TypeSourceInfo *TInfo,
@@ -2235,7 +2243,17 @@ public:
bool CheckNontrivialField(FieldDecl *FD);
void DiagnoseNontrivial(const CXXRecordDecl *Record, CXXSpecialMember CSM);
+
+ enum TrivialABIHandling {
+ /// The triviality of a method unaffected by "trivial_abi".
+ TAH_IgnoreTrivialABI,
+
+ /// The triviality of a method affected by "trivial_abi".
+ TAH_ConsiderTrivialABI
+ };
+
bool SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM,
+ TrivialABIHandling TAH = TAH_IgnoreTrivialABI,
bool Diagnose = false);
CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD);
void ActOnLastBitfield(SourceLocation DeclStart,
@@ -2245,10 +2263,9 @@ public:
tok::ObjCKeywordKind visibility);
// This is used for both record definitions and ObjC interface declarations.
- void ActOnFields(Scope* S, SourceLocation RecLoc, Decl *TagDecl,
- ArrayRef<Decl *> Fields,
- SourceLocation LBrac, SourceLocation RBrac,
- AttributeList *AttrList);
+ void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl,
+ ArrayRef<Decl *> Fields, SourceLocation LBrac,
+ SourceLocation RBrac, const ParsedAttributesView &AttrList);
/// ActOnTagStartDefinition - Invoked when we have entered the
/// scope of a tag's definition (e.g., for an enumeration, class,
@@ -2263,7 +2280,7 @@ public:
typedef void *SkippedDefinitionContext;
- /// \brief Invoked when we enter a tag definition that we're skipping.
+ /// Invoked when we enter a tag definition that we're skipping.
SkippedDefinitionContext ActOnTagStartSkippedDefinition(Scope *S, Decl *TD);
Decl *ActOnObjCContainerStartDefinition(Decl *IDecl);
@@ -2285,7 +2302,7 @@ public:
void ActOnObjCContainerFinishDefinition();
- /// \brief Invoked when we must temporarily exit the objective-c container
+ /// Invoked when we must temporarily exit the objective-c container
/// scope for parsing/looking-up C constructs.
///
/// Must be followed by a call to \see ActOnObjCReenterContainerContext
@@ -2303,8 +2320,7 @@ public:
Expr *val);
bool CheckEnumUnderlyingType(TypeSourceInfo *TI);
bool CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped,
- QualType EnumUnderlyingTy,
- bool EnumUnderlyingIsImplicit,
+ QualType EnumUnderlyingTy, bool IsFixed,
const EnumDecl *Prev);
/// Determine whether the body of an anonymous enumeration should be skipped.
@@ -2314,12 +2330,11 @@ public:
Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant,
SourceLocation IdLoc, IdentifierInfo *Id,
- AttributeList *Attrs, SourceLocation EqualLoc,
- Expr *Val);
+ const ParsedAttributesView &Attrs,
+ SourceLocation EqualLoc, Expr *Val);
void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,
- Decl *EnumDecl,
- ArrayRef<Decl *> Elements,
- Scope *S, AttributeList *Attr);
+ Decl *EnumDecl, ArrayRef<Decl *> Elements, Scope *S,
+ const ParsedAttributesView &Attr);
DeclContext *getContainingDC(DeclContext *DC);
@@ -2356,7 +2371,7 @@ public:
/// Add this decl to the scope shadowed decl chains.
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true);
- /// \brief Make the given externally-produced declaration visible at the
+ /// Make the given externally-produced declaration visible at the
/// top level scope.
///
/// \param D The externally-produced declaration to push.
@@ -2383,18 +2398,18 @@ public:
TypeSourceInfo *TInfo);
bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New);
- /// \brief Describes the kind of merge to perform for availability
+ /// Describes the kind of merge to perform for availability
/// attributes (including "deprecated", "unavailable", and "availability").
enum AvailabilityMergeKind {
- /// \brief Don't merge availability attributes at all.
+ /// Don't merge availability attributes at all.
AMK_None,
- /// \brief Merge availability attributes for a redeclaration, which requires
+ /// Merge availability attributes for a redeclaration, which requires
/// an exact match.
AMK_Redeclaration,
- /// \brief Merge availability attributes for an override, which requires
+ /// Merge availability attributes for an override, which requires
/// an exact match or a weakening of constraints.
AMK_Override,
- /// \brief Merge availability attributes for an implementation of
+ /// Merge availability attributes for an implementation of
/// a protocol requirement.
AMK_ProtocolImplementation,
};
@@ -2432,6 +2447,8 @@ public:
int FirstArg, unsigned AttrSpellingListIndex);
SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name,
unsigned AttrSpellingListIndex);
+ CodeSegAttr *mergeCodeSegAttr(Decl *D, SourceRange Range, StringRef Name,
+ unsigned AttrSpellingListIndex);
AlwaysInlineAttr *mergeAlwaysInlineAttr(Decl *D, SourceRange Range,
IdentifierInfo *Ident,
unsigned AttrSpellingListIndex);
@@ -2496,7 +2513,7 @@ public:
bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl,
bool ConsiderCudaAttrs = true);
- /// \brief Checks availability of the function depending on the current
+ /// Checks availability of the function depending on the current
/// function context.Inside an unavailable function,unavailability is ignored.
///
/// \returns true if \p FD is unavailable and current context is inside
@@ -2568,6 +2585,11 @@ public:
NamedDecl *FoundDecl,
CXXMethodDecl *Method);
+ /// Check that the lifetime of the initializer (and its subobjects) is
+ /// sufficient for initializing the entity, and perform lifetime extension
+ /// (when permitted) if not.
+ void checkInitializerLifetime(const InitializedEntity &Entity, Expr *Init);
+
ExprResult PerformContextuallyConvertToBool(Expr *From);
ExprResult PerformContextuallyConvertToObjCPointer(Expr *From);
@@ -2584,7 +2606,7 @@ public:
ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,
APValue &Value, CCEKind CCE);
- /// \brief Abstract base class used to perform a contextual implicit
+ /// Abstract base class used to perform a contextual implicit
/// conversion from an expression to any type passing a filter.
class ContextualImplicitConverter {
public:
@@ -2595,38 +2617,38 @@ public:
bool SuppressConversion = false)
: Suppress(Suppress), SuppressConversion(SuppressConversion) {}
- /// \brief Determine whether the specified type is a valid destination type
+ /// Determine whether the specified type is a valid destination type
/// for this conversion.
virtual bool match(QualType T) = 0;
- /// \brief Emits a diagnostic complaining that the expression does not have
+ /// Emits a diagnostic complaining that the expression does not have
/// integral or enumeration type.
virtual SemaDiagnosticBuilder
diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) = 0;
- /// \brief Emits a diagnostic when the expression has incomplete class type.
+ /// Emits a diagnostic when the expression has incomplete class type.
virtual SemaDiagnosticBuilder
diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) = 0;
- /// \brief Emits a diagnostic when the only matching conversion function
+ /// Emits a diagnostic when the only matching conversion function
/// is explicit.
virtual SemaDiagnosticBuilder diagnoseExplicitConv(
Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0;
- /// \brief Emits a note for the explicit conversion function.
+ /// Emits a note for the explicit conversion function.
virtual SemaDiagnosticBuilder
noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0;
- /// \brief Emits a diagnostic when there are multiple possible conversion
+ /// Emits a diagnostic when there are multiple possible conversion
/// functions.
virtual SemaDiagnosticBuilder
diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) = 0;
- /// \brief Emits a note for one of the candidate conversions.
+ /// Emits a note for one of the candidate conversions.
virtual SemaDiagnosticBuilder
noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0;
- /// \brief Emits a diagnostic when we picked a conversion function
+ /// Emits a diagnostic when we picked a conversion function
/// (for cases when we are not allowed to pick a conversion function).
virtual SemaDiagnosticBuilder diagnoseConversion(
Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0;
@@ -2651,7 +2673,7 @@ public:
return diagnoseNotInt(S, Loc, T);
}
- /// \brief Emits a diagnostic complaining that the expression does not have
+ /// Emits a diagnostic complaining that the expression does not have
/// integral or enumeration type.
virtual SemaDiagnosticBuilder
diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) = 0;
@@ -2986,7 +3008,7 @@ public:
/// the ability to distinguish among them.
//@{
- /// @brief Describes the kind of name lookup to perform.
+ /// Describes the kind of name lookup to perform.
enum LookupNameKind {
/// Ordinary name lookup, which finds ordinary names (functions,
/// variables, typedefs, etc.) in C and most kinds of names
@@ -3028,22 +3050,22 @@ public:
LookupObjCProtocolName,
/// Look up implicit 'self' parameter of an objective-c method.
LookupObjCImplicitSelfParam,
- /// \brief Look up the name of an OpenMP user-defined reduction operation.
+ /// Look up the name of an OpenMP user-defined reduction operation.
LookupOMPReductionName,
- /// \brief Look up any declaration with any name.
+ /// Look up any declaration with any name.
LookupAnyName
};
- /// \brief Specifies whether (or how) name lookup is being performed for a
+ /// Specifies whether (or how) name lookup is being performed for a
/// redeclaration (vs. a reference).
enum RedeclarationKind {
- /// \brief The lookup is a reference to this name that is not for the
+ /// The lookup is a reference to this name that is not for the
/// purpose of redeclaring the name.
NotForRedeclaration = 0,
- /// \brief The lookup results will be used for redeclaration of a name,
+ /// The lookup results will be used for redeclaration of a name,
/// if an entity by that name already exists and is visible.
ForVisibleRedeclaration,
- /// \brief The lookup results will be used for redeclaration of a name
+ /// The lookup results will be used for redeclaration of a name
/// with external linkage; non-visible lookup results with external linkage
/// may also be found.
ForExternalRedeclaration
@@ -3060,23 +3082,23 @@ public:
return ForExternalRedeclaration;
}
- /// \brief The possible outcomes of name lookup for a literal operator.
+ /// The possible outcomes of name lookup for a literal operator.
enum LiteralOperatorLookupResult {
- /// \brief The lookup resulted in an error.
+ /// The lookup resulted in an error.
LOLR_Error,
- /// \brief The lookup found no match but no diagnostic was issued.
+ /// The lookup found no match but no diagnostic was issued.
LOLR_ErrorNoDiagnostic,
- /// \brief The lookup found a single 'cooked' literal operator, which
+ /// The lookup found a single 'cooked' literal operator, which
/// expects a normal literal to be built and passed to it.
LOLR_Cooked,
- /// \brief The lookup found a single 'raw' literal operator, which expects
+ /// The lookup found a single 'raw' literal operator, which expects
/// a string literal containing the spelling of the literal token.
LOLR_Raw,
- /// \brief The lookup found an overload set of literal operator templates,
+ /// The lookup found an overload set of literal operator templates,
/// which expect the characters of the spelling of the literal token to be
/// passed as a non-type template argument pack.
LOLR_Template,
- /// \brief The lookup found an overload set of literal operator templates,
+ /// The lookup found an overload set of literal operator templates,
/// which expect the character type and characters of the spelling of the
/// string literal token to be passed as template arguments.
LOLR_StringTemplate
@@ -3106,25 +3128,25 @@ private:
TypoExprState &operator=(TypoExprState &&other) noexcept;
};
- /// \brief The set of unhandled TypoExprs and their associated state.
+ /// The set of unhandled TypoExprs and their associated state.
llvm::MapVector<TypoExpr *, TypoExprState> DelayedTypos;
- /// \brief Creates a new TypoExpr AST node.
+ /// Creates a new TypoExpr AST node.
TypoExpr *createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC,
TypoDiagnosticGenerator TDG,
TypoRecoveryCallback TRC);
- // \brief The set of known/encountered (unique, canonicalized) NamespaceDecls.
+ // The set of known/encountered (unique, canonicalized) NamespaceDecls.
//
// The boolean value will be true to indicate that the namespace was loaded
// from an AST/PCH file, or false otherwise.
llvm::MapVector<NamespaceDecl*, bool> KnownNamespaces;
- /// \brief Whether we have already loaded known namespaces from an extenal
+ /// Whether we have already loaded known namespaces from an extenal
/// source.
bool LoadedExternalKnownNamespaces;
- /// \brief Helper for CorrectTypo and CorrectTypoDelayed used to create and
+ /// Helper for CorrectTypo and CorrectTypoDelayed used to create and
/// populate a new TypoCorrectionConsumer. Returns nullptr if typo correction
/// should be skipped entirely.
std::unique_ptr<TypoCorrectionConsumer>
@@ -3139,10 +3161,10 @@ private:
public:
const TypoExprState &getTypoExprState(TypoExpr *TE) const;
- /// \brief Clears the state of the given TypoExpr.
+ /// Clears the state of the given TypoExpr.
void clearDelayedTypo(TypoExpr *TE);
- /// \brief Look up a name, looking for a single declaration. Return
+ /// Look up a name, looking for a single declaration. Return
/// null if the results were absent, ambiguous, or overloaded.
///
/// It is preferable to use the elaborated form and explicitly handle
@@ -3199,11 +3221,13 @@ public:
void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
VisibleDeclConsumer &Consumer,
- bool IncludeGlobalScope = true);
+ bool IncludeGlobalScope = true,
+ bool LoadExternal = true);
void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
VisibleDeclConsumer &Consumer,
bool IncludeGlobalScope = true,
- bool IncludeDependentBases = false);
+ bool IncludeDependentBases = false,
+ bool LoadExternal = true);
enum CorrectTypoKind {
CTK_NonError, // CorrectTypo used in a non error recovery situation.
@@ -3230,7 +3254,7 @@ public:
bool EnteringContext = false,
const ObjCObjectPointerType *OPT = nullptr);
- /// \brief Process any TypoExprs in the given Expr and its children,
+ /// Process any TypoExprs in the given Expr and its children,
/// generating diagnostics as appropriate and returning a new Expr if there
/// were typos that were all successfully corrected and ExprError if one or
/// more typos could not be corrected.
@@ -3308,11 +3332,12 @@ public:
// Decl attributes - this routine is the top level dispatcher.
void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
// Helper for delayed processing of attributes.
- void ProcessDeclAttributeDelayed(Decl *D, const AttributeList *AttrList);
- void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL,
- bool IncludeCXX11Attributes = true);
+ void ProcessDeclAttributeDelayed(Decl *D,
+ const ParsedAttributesView &AttrList);
+ void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AL,
+ bool IncludeCXX11Attributes = true);
bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
- const AttributeList *AttrList);
+ const ParsedAttributesView &AttrList);
void checkUnusedDeclAttributes(Declarator &D);
@@ -3322,13 +3347,13 @@ public:
/// type as valid.
bool isValidPointerAttrType(QualType T, bool RefOkay = false);
- bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
- bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
+ bool CheckRegparmAttr(const ParsedAttr &attr, unsigned &value);
+ bool CheckCallingConvAttr(const ParsedAttr &attr, CallingConv &CC,
const FunctionDecl *FD = nullptr);
- bool CheckNoReturnAttr(const AttributeList &attr);
- bool CheckNoCallerSavedRegsAttr(const AttributeList &attr);
- bool checkStringLiteralArgumentAttr(const AttributeList &Attr,
- unsigned ArgNum, StringRef &Str,
+ bool CheckAttrTarget(const ParsedAttr &CurrAttr);
+ bool CheckAttrNoArgs(const ParsedAttr &CurrAttr);
+ bool checkStringLiteralArgumentAttr(const ParsedAttr &Attr, unsigned ArgNum,
+ StringRef &Str,
SourceLocation *ArgLocation = nullptr);
bool checkSectionName(SourceLocation LiteralLoc, StringRef Str);
bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str);
@@ -3377,8 +3402,9 @@ public:
bool isContextSensitive,
bool allowArrayTypes);
- /// \brief Stmt attributes - this routine is the top level dispatcher.
- StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs,
+ /// Stmt attributes - this routine is the top level dispatcher.
+ StmtResult ProcessStmtAttributes(Stmt *Stmt,
+ const ParsedAttributesView &Attrs,
SourceRange Range);
void WarnConflictingTypedMethods(ObjCMethodDecl *Method,
@@ -3520,7 +3546,7 @@ public:
/// warns each time an exact match is found.
void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP);
- /// \brief Add the given method to the list of globally-known methods.
+ /// Add the given method to the list of globally-known methods.
void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method);
private:
@@ -3535,7 +3561,7 @@ private:
bool instance);
public:
- /// \brief - Returns instance or factory methods in global method pool for
+ /// - Returns instance or factory methods in global method pool for
/// given selector. It checks the desired kind first, if none is found, and
/// parameter checkTheOther is set, it then checks the other kind. If no such
/// method or only one method is found, function returns false; otherwise, it
@@ -3557,14 +3583,14 @@ public:
bool receiverIdOrClass);
private:
- /// \brief - Returns a selector which best matches given argument list or
+ /// - Returns a selector which best matches given argument list or
/// nullptr if none could be found
ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args,
bool IsInstance,
SmallVectorImpl<ObjCMethodDecl*>& Methods);
- /// \brief Record the typo correction failure and return an empty correction.
+ /// Record the typo correction failure and return an empty correction.
TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc,
bool RecordFailure = true) {
if (RecordFailure)
@@ -3664,16 +3690,16 @@ public:
StmtResult ActOnNullStmt(SourceLocation SemiLoc,
bool HasLeadingEmptyMacro = false);
- void ActOnStartOfCompoundStmt();
+ void ActOnStartOfCompoundStmt(bool IsStmtExpr);
void ActOnFinishOfCompoundStmt();
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
ArrayRef<Stmt *> Elts, bool isStmtExpr);
- /// \brief A RAII object to enter scope of a compound statement.
+ /// A RAII object to enter scope of a compound statement.
class CompoundScopeRAII {
public:
- CompoundScopeRAII(Sema &S): S(S) {
- S.ActOnStartOfCompoundStmt();
+ CompoundScopeRAII(Sema &S, bool IsStmtExpr = false) : S(S) {
+ S.ActOnStartOfCompoundStmt(IsStmtExpr);
}
~CompoundScopeRAII() {
@@ -3701,9 +3727,10 @@ public:
SourceLocation EndLoc);
void ActOnForEachDeclStmt(DeclGroupPtrTy Decl);
StmtResult ActOnForEachLValueExpr(Expr *E);
- StmtResult ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
- SourceLocation DotDotDotLoc, Expr *RHSVal,
- SourceLocation ColonLoc);
+ ExprResult ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val);
+ StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS,
+ SourceLocation DotDotDotLoc, ExprResult RHS,
+ SourceLocation ColonLoc);
void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt);
StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
@@ -3797,10 +3824,22 @@ public:
RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD,
SourceLocation Loc,
unsigned NumParams);
+
+ enum CopyElisionSemanticsKind {
+ CES_Strict = 0,
+ CES_AllowParameters = 1,
+ CES_AllowDifferentTypes = 2,
+ CES_AllowExceptionVariables = 4,
+ CES_FormerDefault = (CES_AllowParameters),
+ CES_Default = (CES_AllowParameters | CES_AllowDifferentTypes),
+ CES_AsIfByStdMove = (CES_AllowParameters | CES_AllowDifferentTypes |
+ CES_AllowExceptionVariables),
+ };
+
VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E,
- bool AllowParamOrMoveConstructible);
+ CopyElisionSemanticsKind CESK);
bool isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD,
- bool AllowParamOrMoveConstructible);
+ CopyElisionSemanticsKind CESK);
StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
Scope *CurScope);
@@ -3889,7 +3928,7 @@ public:
bool ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const;
- /// \brief If it's a file scoped decl that must warn if not used, keep track
+ /// If it's a file scoped decl that must warn if not used, keep track
/// of it.
void MarkUnusedFileScopedDecl(const DeclaratorDecl *D);
@@ -3918,7 +3957,7 @@ public:
void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr,
SourceLocation OpLoc);
- /// \brief Warn if we're implicitly casting from a _Nullable pointer type to a
+ /// Warn if we're implicitly casting from a _Nullable pointer type to a
/// _Nonnull one.
void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType,
SourceLocation Loc);
@@ -3941,7 +3980,7 @@ public:
void redelayDiagnostics(sema::DelayedDiagnosticPool &pool);
- void DiagnoseAvailabilityOfDecl(NamedDecl *D, SourceLocation Loc,
+ void DiagnoseAvailabilityOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
const ObjCInterfaceDecl *UnknownObjCClass,
bool ObjCPropertyAccess,
bool AvoidPartialAvailabilityChecks = false);
@@ -3949,14 +3988,14 @@ public:
bool makeUnavailableInSystemHeader(SourceLocation loc,
UnavailableAttr::ImplicitReason reason);
- /// \brief Issue any -Wunguarded-availability warnings in \c FD
+ /// Issue any -Wunguarded-availability warnings in \c FD
void DiagnoseUnguardedAvailabilityViolations(Decl *FD);
//===--------------------------------------------------------------------===//
// Expression Parsing Callbacks: SemaExpr.cpp.
bool CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid);
- bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
+ bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
const ObjCInterfaceDecl *UnknownObjCClass = nullptr,
bool ObjCPropertyAccess = false,
bool AvoidPartialAvailabilityChecks = false);
@@ -3969,13 +4008,15 @@ public:
void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
ArrayRef<Expr *> Args);
- void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
- Decl *LambdaContextDecl = nullptr,
- bool IsDecltype = false);
+ void PushExpressionEvaluationContext(
+ ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl = nullptr,
+ ExpressionEvaluationContextRecord::ExpressionKind Type =
+ ExpressionEvaluationContextRecord::EK_Other);
enum ReuseLambdaContextDecl_t { ReuseLambdaContextDecl };
- void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
- ReuseLambdaContextDecl_t,
- bool IsDecltype = false);
+ void PushExpressionEvaluationContext(
+ ExpressionEvaluationContext NewContext, ReuseLambdaContextDecl_t,
+ ExpressionEvaluationContextRecord::ExpressionKind Type =
+ ExpressionEvaluationContextRecord::EK_Other);
void PopExpressionEvaluationContext();
void DiscardCleanupsInEvaluationContext();
@@ -4011,7 +4052,7 @@ public:
TryCapture_Implicit, TryCapture_ExplicitByVal, TryCapture_ExplicitByRef
};
- /// \brief Try to capture the given variable.
+ /// Try to capture the given variable.
///
/// \param Var The variable to capture.
///
@@ -4050,15 +4091,15 @@ public:
QualType &DeclRefType,
const unsigned *const FunctionScopeIndexToStopAt);
- /// \brief Try to capture the given variable.
+ /// Try to capture the given variable.
bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
TryCaptureKind Kind = TryCapture_Implicit,
SourceLocation EllipsisLoc = SourceLocation());
- /// \brief Checks if the variable must be captured.
+ /// Checks if the variable must be captured.
bool NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc);
- /// \brief Given a variable, determine the type that a reference to that
+ /// Given a variable, determine the type that a reference to that
/// variable will have in the given scope.
QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc);
@@ -4069,18 +4110,18 @@ public:
void MarkDeclarationsReferencedInExpr(Expr *E,
bool SkipLocalVariables = false);
- /// \brief Try to recover by turning the given expression into a
+ /// Try to recover by turning the given expression into a
/// call. Returns true if recovery was attempted or an error was
/// emitted; this may also leave the ExprResult invalid.
bool tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD,
bool ForceComplain = false,
bool (*IsPlausibleResult)(QualType) = nullptr);
- /// \brief Figure out if an expression could be turned into a call.
+ /// Figure out if an expression could be turned into a call.
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy,
UnresolvedSetImpl &NonTemplateOverloads);
- /// \brief Conditionally issue a diagnostic based on the current
+ /// Conditionally issue a diagnostic based on the current
/// evaluation context.
///
/// \param Statement If Statement is non-null, delay reporting the
@@ -4222,6 +4263,7 @@ public:
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
tok::TokenKind Op, Expr *Input);
+ bool isQualifiedMemberAccess(Expr *E);
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc);
ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
@@ -4354,7 +4396,7 @@ public:
Expr *Op);
CastKind PrepareScalarCast(ExprResult &src, QualType destType);
- /// \brief Build an altivec or OpenCL literal.
+ /// Build an altivec or OpenCL literal.
ExprResult BuildVectorLiteral(SourceLocation LParenLoc,
SourceLocation RParenLoc, Expr *E,
TypeSourceInfo *TInfo);
@@ -4446,19 +4488,19 @@ public:
bool CheckCaseExpression(Expr *E);
- /// \brief Describes the result of an "if-exists" condition check.
+ /// Describes the result of an "if-exists" condition check.
enum IfExistsResult {
- /// \brief The symbol exists.
+ /// The symbol exists.
IER_Exists,
- /// \brief The symbol does not exist.
+ /// The symbol does not exist.
IER_DoesNotExist,
- /// \brief The name is a dependent name, so the results will differ
+ /// The name is a dependent name, so the results will differ
/// from one instantiation to the next.
IER_Dependent,
- /// \brief An error occurred.
+ /// An error occurred.
IER_Error
};
@@ -4520,11 +4562,10 @@ public:
// Act on C++ namespaces
Decl *ActOnStartNamespaceDef(Scope *S, SourceLocation InlineLoc,
SourceLocation NamespaceLoc,
- SourceLocation IdentLoc,
- IdentifierInfo *Ident,
+ SourceLocation IdentLoc, IdentifierInfo *Ident,
SourceLocation LBrace,
- AttributeList *AttrList,
- UsingDirectiveDecl * &UsingDecl);
+ const ParsedAttributesView &AttrList,
+ UsingDirectiveDecl *&UsingDecl);
void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace);
NamespaceDecl *getStdNamespace() const;
@@ -4535,27 +4576,41 @@ public:
CXXRecordDecl *getStdBadAlloc() const;
EnumDecl *getStdAlignValT() const;
- /// \brief Tests whether Ty is an instance of std::initializer_list and, if
+private:
+ // A cache representing if we've fully checked the various comparison category
+ // types stored in ASTContext. The bit-index corresponds to the integer value
+ // of a ComparisonCategoryType enumerator.
+ llvm::SmallBitVector FullyCheckedComparisonCategories;
+
+public:
+ /// Lookup the specified comparison category types in the standard
+ /// library, an check the VarDecls possibly returned by the operator<=>
+ /// builtins for that type.
+ ///
+ /// \return The type of the comparison category type corresponding to the
+ /// specified Kind, or a null type if an error occurs
+ QualType CheckComparisonCategoryType(ComparisonCategoryType Kind,
+ SourceLocation Loc);
+
+ /// Tests whether Ty is an instance of std::initializer_list and, if
/// it is and Element is not NULL, assigns the element type to Element.
bool isStdInitializerList(QualType Ty, QualType *Element);
- /// \brief Looks for the std::initializer_list template and instantiates it
+ /// Looks for the std::initializer_list template and instantiates it
/// with Element, or emits an error if it's not found.
///
/// \returns The instantiated template, or null on error.
QualType BuildStdInitializerList(QualType Element, SourceLocation Loc);
- /// \brief Determine whether Ctor is an initializer-list constructor, as
+ /// Determine whether Ctor is an initializer-list constructor, as
/// defined in [dcl.init.list]p2.
bool isInitListConstructor(const FunctionDecl *Ctor);
- Decl *ActOnUsingDirective(Scope *CurScope,
- SourceLocation UsingLoc,
- SourceLocation NamespcLoc,
- CXXScopeSpec &SS,
+ Decl *ActOnUsingDirective(Scope *CurScope, SourceLocation UsingLoc,
+ SourceLocation NamespcLoc, CXXScopeSpec &SS,
SourceLocation IdentLoc,
IdentifierInfo *NamespcName,
- AttributeList *AttrList);
+ const ParsedAttributesView &AttrList);
void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir);
@@ -4586,15 +4641,11 @@ public:
const DeclarationNameInfo &NameInfo,
SourceLocation NameLoc);
- NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
- SourceLocation UsingLoc,
- bool HasTypenameKeyword,
- SourceLocation TypenameLoc,
- CXXScopeSpec &SS,
- DeclarationNameInfo NameInfo,
- SourceLocation EllipsisLoc,
- AttributeList *AttrList,
- bool IsInstantiation);
+ NamedDecl *BuildUsingDeclaration(
+ Scope *S, AccessSpecifier AS, SourceLocation UsingLoc,
+ bool HasTypenameKeyword, SourceLocation TypenameLoc, CXXScopeSpec &SS,
+ DeclarationNameInfo NameInfo, SourceLocation EllipsisLoc,
+ const ParsedAttributesView &AttrList, bool IsInstantiation);
NamedDecl *BuildUsingPackDecl(NamedDecl *InstantiatedFrom,
ArrayRef<NamedDecl *> Expansions);
@@ -4607,22 +4658,16 @@ public:
findInheritingConstructor(SourceLocation Loc, CXXConstructorDecl *BaseCtor,
ConstructorUsingShadowDecl *DerivedShadow);
- Decl *ActOnUsingDeclaration(Scope *CurScope,
- AccessSpecifier AS,
+ Decl *ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS,
SourceLocation UsingLoc,
- SourceLocation TypenameLoc,
- CXXScopeSpec &SS,
- UnqualifiedId &Name,
- SourceLocation EllipsisLoc,
- AttributeList *AttrList);
- Decl *ActOnAliasDeclaration(Scope *CurScope,
- AccessSpecifier AS,
+ SourceLocation TypenameLoc, CXXScopeSpec &SS,
+ UnqualifiedId &Name, SourceLocation EllipsisLoc,
+ const ParsedAttributesView &AttrList);
+ Decl *ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS,
MultiTemplateParamsArg TemplateParams,
- SourceLocation UsingLoc,
- UnqualifiedId &Name,
- AttributeList *AttrList,
- TypeResult Type,
- Decl *DeclFromDeclSpec);
+ SourceLocation UsingLoc, UnqualifiedId &Name,
+ const ParsedAttributesView &AttrList,
+ TypeResult Type, Decl *DeclFromDeclSpec);
/// BuildCXXConstructExpr - Creates a complete call to a constructor,
/// including handling of its default argument expressions.
@@ -4677,7 +4722,7 @@ public:
/// constructed variable.
void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
- /// \brief Helper class that collects exception specifications for
+ /// Helper class that collects exception specifications for
/// implicitly-declared special member functions.
class ImplicitExceptionSpecification {
// Pointer to allow copying
@@ -4704,26 +4749,26 @@ public:
ComputedEST = EST_DynamicNone;
}
- /// \brief Get the computed exception specification type.
+ /// Get the computed exception specification type.
ExceptionSpecificationType getExceptionSpecType() const {
- assert(ComputedEST != EST_ComputedNoexcept &&
+ assert(!isComputedNoexcept(ComputedEST) &&
"noexcept(expr) should not be a possible result");
return ComputedEST;
}
- /// \brief The number of exceptions in the exception specification.
+ /// The number of exceptions in the exception specification.
unsigned size() const { return Exceptions.size(); }
- /// \brief The set of exceptions in the exception specification.
+ /// The set of exceptions in the exception specification.
const QualType *data() const { return Exceptions.data(); }
- /// \brief Integrate another called method into the collected data.
+ /// Integrate another called method into the collected data.
void CalledDecl(SourceLocation CallLoc, const CXXMethodDecl *Method);
- /// \brief Integrate an invoked expression into the collected data.
+ /// Integrate an invoked expression into the collected data.
void CalledExpr(Expr *E);
- /// \brief Overwrite an EPI's exception specification with this
+ /// Overwrite an EPI's exception specification with this
/// computed exception specification.
FunctionProtoType::ExceptionSpecInfo getExceptionSpec() const {
FunctionProtoType::ExceptionSpecInfo ESI;
@@ -4734,7 +4779,7 @@ public:
/// C++11 [except.spec]p14:
/// The exception-specification is noexcept(false) if the set of
/// potential exceptions of the special member function contains "any"
- ESI.Type = EST_ComputedNoexcept;
+ ESI.Type = EST_NoexceptFalse;
ESI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(),
tok::kw_false).get();
}
@@ -4742,50 +4787,55 @@ public:
}
};
- /// \brief Determine what sort of exception specification a defaulted
+ /// Determine what sort of exception specification a defaulted
/// copy constructor of a class will have.
ImplicitExceptionSpecification
ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc,
CXXMethodDecl *MD);
- /// \brief Determine what sort of exception specification a defaulted
+ /// Determine what sort of exception specification a defaulted
/// default constructor of a class will have, and whether the parameter
/// will be const.
ImplicitExceptionSpecification
ComputeDefaultedCopyCtorExceptionSpec(CXXMethodDecl *MD);
- /// \brief Determine what sort of exception specification a defautled
+ /// Determine what sort of exception specification a defautled
/// copy assignment operator of a class will have, and whether the
/// parameter will be const.
ImplicitExceptionSpecification
ComputeDefaultedCopyAssignmentExceptionSpec(CXXMethodDecl *MD);
- /// \brief Determine what sort of exception specification a defaulted move
+ /// Determine what sort of exception specification a defaulted move
/// constructor of a class will have.
ImplicitExceptionSpecification
ComputeDefaultedMoveCtorExceptionSpec(CXXMethodDecl *MD);
- /// \brief Determine what sort of exception specification a defaulted move
+ /// Determine what sort of exception specification a defaulted move
/// assignment operator of a class will have.
ImplicitExceptionSpecification
ComputeDefaultedMoveAssignmentExceptionSpec(CXXMethodDecl *MD);
- /// \brief Determine what sort of exception specification a defaulted
+ /// Determine what sort of exception specification a defaulted
/// destructor of a class will have.
ImplicitExceptionSpecification
ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD);
- /// \brief Determine what sort of exception specification an inheriting
+ /// Determine what sort of exception specification an inheriting
/// constructor of a class will have.
ImplicitExceptionSpecification
ComputeInheritingCtorExceptionSpec(SourceLocation Loc,
CXXConstructorDecl *CD);
- /// \brief Evaluate the implicit exception specification for a defaulted
+ /// Evaluate the implicit exception specification for a defaulted
/// special member function.
void EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD);
- /// \brief Check the given exception-specification and update the
+ /// Check the given noexcept-specifier, convert its expression, and compute
+ /// the appropriate ExceptionSpecificationType.
+ ExprResult ActOnNoexceptSpec(SourceLocation NoexceptLoc, Expr *NoexceptExpr,
+ ExceptionSpecificationType &EST);
+
+ /// Check the given exception-specification and update the
/// exception specification information with the results.
void checkExceptionSpecification(bool IsTopLevel,
ExceptionSpecificationType EST,
@@ -4795,11 +4845,11 @@ public:
SmallVectorImpl<QualType> &Exceptions,
FunctionProtoType::ExceptionSpecInfo &ESI);
- /// \brief Determine if we're in a case where we need to (incorrectly) eagerly
+ /// Determine if we're in a case where we need to (incorrectly) eagerly
/// parse an exception specification to work around a libstdc++ bug.
bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D);
- /// \brief Add an exception-specification to the given member function
+ /// Add an exception-specification to the given member function
/// (or member function template). The exception-specification was parsed
/// after the method itself was declared.
void actOnDelayedExceptionSpecification(Decl *Method,
@@ -4811,13 +4861,13 @@ public:
class InheritedConstructorInfo;
- /// \brief Determine if a special member function should have a deleted
+ /// Determine if a special member function should have a deleted
/// definition when it is defaulted.
bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
InheritedConstructorInfo *ICI = nullptr,
bool Diagnose = false);
- /// \brief Declare the implicit default constructor for the given class.
+ /// Declare the implicit default constructor for the given class.
///
/// \param ClassDecl The class declaration into which the implicit
/// default constructor will be added.
@@ -4831,7 +4881,7 @@ public:
void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
CXXConstructorDecl *Constructor);
- /// \brief Declare the implicit destructor for the given class.
+ /// Declare the implicit destructor for the given class.
///
/// \param ClassDecl The class declaration into which the implicit
/// destructor will be added.
@@ -4844,18 +4894,18 @@ public:
void DefineImplicitDestructor(SourceLocation CurrentLocation,
CXXDestructorDecl *Destructor);
- /// \brief Build an exception spec for destructors that don't have one.
+ /// Build an exception spec for destructors that don't have one.
///
/// C++11 says that user-defined destructors with no exception spec get one
/// that looks as if the destructor was implicitly declared.
void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,
CXXDestructorDecl *Destructor);
- /// \brief Define the specified inheriting constructor.
+ /// Define the specified inheriting constructor.
void DefineInheritingConstructor(SourceLocation UseLoc,
CXXConstructorDecl *Constructor);
- /// \brief Declare the implicit copy constructor for the given class.
+ /// Declare the implicit copy constructor for the given class.
///
/// \param ClassDecl The class declaration into which the implicit
/// copy constructor will be added.
@@ -4868,7 +4918,7 @@ public:
void DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
CXXConstructorDecl *Constructor);
- /// \brief Declare the implicit move constructor for the given class.
+ /// Declare the implicit move constructor for the given class.
///
/// \param ClassDecl The Class declaration into which the implicit
/// move constructor will be added.
@@ -4882,7 +4932,7 @@ public:
void DefineImplicitMoveConstructor(SourceLocation CurrentLocation,
CXXConstructorDecl *Constructor);
- /// \brief Declare the implicit copy assignment operator for the given class.
+ /// Declare the implicit copy assignment operator for the given class.
///
/// \param ClassDecl The class declaration into which the implicit
/// copy assignment operator will be added.
@@ -4890,11 +4940,11 @@ public:
/// \returns The implicitly-declared copy assignment operator.
CXXMethodDecl *DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl);
- /// \brief Defines an implicitly-declared copy assignment operator.
+ /// Defines an implicitly-declared copy assignment operator.
void DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
CXXMethodDecl *MethodDecl);
- /// \brief Declare the implicit move assignment operator for the given class.
+ /// Declare the implicit move assignment operator for the given class.
///
/// \param ClassDecl The Class declaration into which the implicit
/// move assignment operator will be added.
@@ -4903,32 +4953,32 @@ public:
/// wasn't declared.
CXXMethodDecl *DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl);
- /// \brief Defines an implicitly-declared move assignment operator.
+ /// Defines an implicitly-declared move assignment operator.
void DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
CXXMethodDecl *MethodDecl);
- /// \brief Force the declaration of any implicitly-declared members of this
+ /// Force the declaration of any implicitly-declared members of this
/// class.
void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class);
- /// \brief Check a completed declaration of an implicit special member.
+ /// Check a completed declaration of an implicit special member.
void CheckImplicitSpecialMemberDeclaration(Scope *S, FunctionDecl *FD);
- /// \brief Determine whether the given function is an implicitly-deleted
+ /// Determine whether the given function is an implicitly-deleted
/// special member function.
bool isImplicitlyDeleted(FunctionDecl *FD);
- /// \brief Check whether 'this' shows up in the type of a static member
+ /// Check whether 'this' shows up in the type of a static member
/// function after the (naturally empty) cv-qualifier-seq would be.
///
/// \returns true if an error occurred.
bool checkThisInStaticMemberFunctionType(CXXMethodDecl *Method);
- /// \brief Whether this' shows up in the exception specification of a static
+ /// Whether this' shows up in the exception specification of a static
/// member function.
bool checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method);
- /// \brief Check whether 'this' shows up in the attributes of the given
+ /// Check whether 'this' shows up in the attributes of the given
/// static member function.
///
/// \returns true if an error occurred.
@@ -4950,6 +5000,9 @@ public:
SourceLocation NameLoc,
IdentifierInfo &Name);
+ ParsedType getConstructorName(IdentifierInfo &II, SourceLocation NameLoc,
+ Scope *S, CXXScopeSpec &SS,
+ bool EnteringContext);
ParsedType getDestructorName(SourceLocation TildeLoc,
IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, CXXScopeSpec &SS,
@@ -5010,7 +5063,7 @@ public:
void *TyOrExpr,
SourceLocation RParenLoc);
- /// \brief Handle a C++1z fold-expression: ( expr op ... op expr ).
+ /// Handle a C++1z fold-expression: ( expr op ... op expr ).
ExprResult ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
tok::TokenKind Operator,
SourceLocation EllipsisLoc, Expr *RHS,
@@ -5025,17 +5078,17 @@ public:
//// ActOnCXXThis - Parse 'this' pointer.
ExprResult ActOnCXXThis(SourceLocation loc);
- /// \brief Try to retrieve the type of the 'this' pointer.
+ /// Try to retrieve the type of the 'this' pointer.
///
/// \returns The type of 'this', if possible. Otherwise, returns a NULL type.
QualType getCurrentThisType();
- /// \brief When non-NULL, the C++ 'this' expression is allowed despite the
+ /// When non-NULL, the C++ 'this' expression is allowed despite the
/// current context not being a non-static member function. In such cases,
/// this provides the type used for 'this'.
QualType CXXThisTypeOverride;
- /// \brief RAII object used to temporarily allow the C++ 'this' expression
+ /// RAII object used to temporarily allow the C++ 'this' expression
/// to be used, with the given qualifiers on the current class type.
class CXXThisScopeRAII {
Sema &S;
@@ -5043,7 +5096,7 @@ public:
bool Enabled;
public:
- /// \brief Introduce a new scope where 'this' may be allowed (when enabled),
+ /// Introduce a new scope where 'this' may be allowed (when enabled),
/// using the given declaration (which is either a class template or a
/// class) along with the given qualifiers.
/// along with the qualifiers placed on '*this'.
@@ -5053,7 +5106,7 @@ public:
~CXXThisScopeRAII();
};
- /// \brief Make sure the value of 'this' is actually available in the current
+ /// Make sure the value of 'this' is actually available in the current
/// context, if it is a potentially evaluated context.
///
/// \param Loc The location at which the capture of 'this' occurs.
@@ -5073,7 +5126,7 @@ public:
const unsigned *const FunctionScopeIndexToStopAt = nullptr,
bool ByCopy = false);
- /// \brief Determine whether the given type is the type of *this that is used
+ /// Determine whether the given type is the type of *this that is used
/// outside of the body of a member function for a type that is currently
/// being defined.
bool isThisOutsideMemberFunctionBody(QualType BaseType);
@@ -5103,14 +5156,16 @@ public:
/// or class type construction ("ClassType(x,y,z)")
/// or creation of a value-initialized type ("int()").
ExprResult ActOnCXXTypeConstructExpr(ParsedType TypeRep,
- SourceLocation LParenLoc,
+ SourceLocation LParenOrBraceLoc,
MultiExprArg Exprs,
- SourceLocation RParenLoc);
+ SourceLocation RParenOrBraceLoc,
+ bool ListInitialization);
ExprResult BuildCXXTypeConstructExpr(TypeSourceInfo *Type,
SourceLocation LParenLoc,
MultiExprArg Exprs,
- SourceLocation RParenLoc);
+ SourceLocation RParenLoc,
+ bool ListInitialization);
/// ActOnCXXNew - Parsed a C++ 'new' expression.
ExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
@@ -5132,11 +5187,29 @@ public:
bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
SourceRange R);
+
+ /// The scope in which to find allocation functions.
+ enum AllocationFunctionScope {
+ /// Only look for allocation functions in the global scope.
+ AFS_Global,
+ /// Only look for allocation functions in the scope of the
+ /// allocated class.
+ AFS_Class,
+ /// Look for allocation functions in both the global scope
+ /// and in the scope of the allocated class.
+ AFS_Both
+ };
+
+ /// Finds the overloads of operator new and delete that are appropriate
+ /// for the allocation.
bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
- bool UseGlobal, QualType AllocType, bool IsArray,
+ AllocationFunctionScope NewScope,
+ AllocationFunctionScope DeleteScope,
+ QualType AllocType, bool IsArray,
bool &PassAlignment, MultiExprArg PlaceArgs,
FunctionDecl *&OperatorNew,
- FunctionDecl *&OperatorDelete);
+ FunctionDecl *&OperatorDelete,
+ bool Diagnose = true);
void DeclareGlobalNewDelete();
void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
ArrayRef<QualType> Params);
@@ -5165,7 +5238,7 @@ public:
ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
SourceLocation RParen);
- /// \brief Parsed one of the type trait support pseudo-functions.
+ /// Parsed one of the type trait support pseudo-functions.
ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
ArrayRef<ParsedType> Args,
SourceLocation RParenLoc);
@@ -5260,7 +5333,7 @@ public:
bool isDependentScopeSpecifier(const CXXScopeSpec &SS);
CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS);
- /// \brief The parser has parsed a global nested-name-specifier '::'.
+ /// The parser has parsed a global nested-name-specifier '::'.
///
/// \param CCLoc The location of the '::'.
///
@@ -5270,7 +5343,7 @@ public:
/// \returns true if an error occurred, false otherwise.
bool ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc, CXXScopeSpec &SS);
- /// \brief The parser has parsed a '__super' nested-name-specifier.
+ /// The parser has parsed a '__super' nested-name-specifier.
///
/// \param SuperLoc The location of the '__super' keyword.
///
@@ -5287,23 +5360,23 @@ public:
bool *CanCorrect = nullptr);
NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
- /// \brief Keeps information about an identifier in a nested-name-spec.
+ /// Keeps information about an identifier in a nested-name-spec.
///
struct NestedNameSpecInfo {
- /// \brief The type of the object, if we're parsing nested-name-specifier in
+ /// The type of the object, if we're parsing nested-name-specifier in
/// a member access expression.
ParsedType ObjectType;
- /// \brief The identifier preceding the '::'.
+ /// The identifier preceding the '::'.
IdentifierInfo *Identifier;
- /// \brief The location of the identifier.
+ /// The location of the identifier.
SourceLocation IdentifierLoc;
- /// \brief The location of the '::'.
+ /// The location of the '::'.
SourceLocation CCLoc;
- /// \brief Creates info object for the most typical case.
+ /// Creates info object for the most typical case.
NestedNameSpecInfo(IdentifierInfo *II, SourceLocation IdLoc,
SourceLocation ColonColonLoc, ParsedType ObjectType = ParsedType())
: ObjectType(ObjectType), Identifier(II), IdentifierLoc(IdLoc),
@@ -5329,7 +5402,7 @@ public:
bool *IsCorrectedToColon = nullptr,
bool OnlyNamespace = false);
- /// \brief The parser has parsed a nested-name-specifier 'identifier::'.
+ /// The parser has parsed a nested-name-specifier 'identifier::'.
///
/// \param S The scope in which this nested-name-specifier occurs.
///
@@ -5372,7 +5445,7 @@ public:
NestedNameSpecInfo &IdInfo,
bool EnteringContext);
- /// \brief The parser has parsed a nested-name-specifier
+ /// The parser has parsed a nested-name-specifier
/// 'template[opt] template-name < template-args >::'.
///
/// \param S The scope in which this nested-name-specifier occurs.
@@ -5406,7 +5479,7 @@ public:
SourceLocation CCLoc,
bool EnteringContext);
- /// \brief Given a C++ nested-name-specifier, produce an annotation value
+ /// Given a C++ nested-name-specifier, produce an annotation value
/// that the parser can use later to reconstruct the given
/// nested-name-specifier.
///
@@ -5416,7 +5489,7 @@ public:
/// nested-name-specifier \p SS.
void *SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS);
- /// \brief Given an annotation pointer for a nested-name-specifier, restore
+ /// Given an annotation pointer for a nested-name-specifier, restore
/// the nested-name-specifier structure.
///
/// \param Annotation The annotation pointer, produced by
@@ -5458,13 +5531,13 @@ public:
/// initializer for the declaration 'Dcl'.
void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl);
- /// \brief Create a new lambda closure type.
+ /// Create a new lambda closure type.
CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange,
TypeSourceInfo *Info,
bool KnownDependent,
LambdaCaptureDefault CaptureDefault);
- /// \brief Start the definition of a lambda expression.
+ /// Start the definition of a lambda expression.
CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class,
SourceRange IntroducerRange,
TypeSourceInfo *MethodType,
@@ -5472,7 +5545,7 @@ public:
ArrayRef<ParmVarDecl *> Params,
bool IsConstexprSpecified);
- /// \brief Endow the lambda scope info with the relevant properties.
+ /// Endow the lambda scope info with the relevant properties.
void buildLambdaScope(sema::LambdaScopeInfo *LSI,
CXXMethodDecl *CallOperator,
SourceRange IntroducerRange,
@@ -5482,7 +5555,7 @@ public:
bool ExplicitResultType,
bool Mutable);
- /// \brief Perform initialization analysis of the init-capture and perform
+ /// Perform initialization analysis of the init-capture and perform
/// any implicit conversions such as an lvalue-to-rvalue conversion if
/// not being used to initialize a reference.
ParsedType actOnLambdaInitCaptureInitialization(
@@ -5495,7 +5568,7 @@ public:
IdentifierInfo *Id,
bool DirectInit, Expr *&Init);
- /// \brief Create a dummy variable within the declcontext of the lambda's
+ /// Create a dummy variable within the declcontext of the lambda's
/// call operator, for name lookup purposes for a lambda init capture.
///
/// CodeGen handles emission of lambda captures, ignoring these dummy
@@ -5505,17 +5578,17 @@ public:
IdentifierInfo *Id,
unsigned InitStyle, Expr *Init);
- /// \brief Build the implicit field for an init-capture.
+ /// Build the implicit field for an init-capture.
FieldDecl *buildInitCaptureField(sema::LambdaScopeInfo *LSI, VarDecl *Var);
- /// \brief Note that we have finished the explicit captures for the
+ /// Note that we have finished the explicit captures for the
/// given lambda.
void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI);
- /// \brief Introduce the lambda parameters into scope.
+ /// Introduce the lambda parameters into scope.
void addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope);
- /// \brief Deduce a block or lambda's return type based on the return
+ /// Deduce a block or lambda's return type based on the return
/// statements present in the body.
void deduceClosureReturnType(sema::CapturingScopeInfo &CSI);
@@ -5536,18 +5609,25 @@ public:
ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
Scope *CurScope);
- /// \brief Does copying/destroying the captured variable have side effects?
- bool CaptureHasSideEffects(const sema::LambdaScopeInfo::Capture &From);
+ /// Does copying/destroying the captured variable have side effects?
+ bool CaptureHasSideEffects(const sema::Capture &From);
- /// \brief Diagnose if an explicit lambda capture is unused.
- void DiagnoseUnusedLambdaCapture(const sema::LambdaScopeInfo::Capture &From);
+ /// Diagnose if an explicit lambda capture is unused. Returns true if a
+ /// diagnostic is emitted.
+ bool DiagnoseUnusedLambdaCapture(SourceRange CaptureRange,
+ const sema::Capture &From);
- /// \brief Complete a lambda-expression having processed and attached the
+ /// Complete a lambda-expression having processed and attached the
/// lambda body.
ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
sema::LambdaScopeInfo *LSI);
- /// \brief Define the "body" of the conversion from a lambda object to a
+ /// Get the return type to use for a lambda's conversion function(s) to
+ /// function pointer type, given the type of the call operator.
+ QualType
+ getLambdaConversionFunctionResultType(const FunctionProtoType *CallOpType);
+
+ /// Define the "body" of the conversion from a lambda object to a
/// function pointer.
///
/// This routine doesn't actually define a sensible body; rather, it fills
@@ -5557,7 +5637,7 @@ public:
void DefineImplicitLambdaToFunctionPointerConversion(
SourceLocation CurrentLoc, CXXConversionDecl *Conv);
- /// \brief Define the "body" of the conversion from a lambda object to a
+ /// Define the "body" of the conversion from a lambda object to a
/// block pointer.
///
/// This routine doesn't actually define a sensible body; rather, it fills
@@ -5645,14 +5725,14 @@ public:
//===--------------------------------------------------------------------===//
// C++ Classes
//
+ CXXRecordDecl *getCurrentClass(Scope *S, const CXXScopeSpec *SS);
bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
const CXXScopeSpec *SS = nullptr);
bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS);
- bool ActOnAccessSpecifier(AccessSpecifier Access,
- SourceLocation ASLoc,
+ bool ActOnAccessSpecifier(AccessSpecifier Access, SourceLocation ASLoc,
SourceLocation ColonLoc,
- AttributeList *Attrs = nullptr);
+ const ParsedAttributesView &Attrs);
NamedDecl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
Declarator &D,
@@ -5726,30 +5806,30 @@ public:
void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc,
CXXRecordDecl *Record);
- /// \brief The list of classes whose vtables have been used within
+ /// The list of classes whose vtables have been used within
/// this translation unit, and the source locations at which the
/// first use occurred.
typedef std::pair<CXXRecordDecl*, SourceLocation> VTableUse;
- /// \brief The list of vtables that are required but have not yet been
+ /// The list of vtables that are required but have not yet been
/// materialized.
SmallVector<VTableUse, 16> VTableUses;
- /// \brief The set of classes whose vtables have been used within
+ /// The set of classes whose vtables have been used within
/// this translation unit, and a bit that will be true if the vtable is
/// required to be emitted (otherwise, it should be emitted only if needed
/// by code generation).
llvm::DenseMap<CXXRecordDecl *, bool> VTablesUsed;
- /// \brief Load any externally-stored vtable uses.
+ /// Load any externally-stored vtable uses.
void LoadExternalVTableUses();
- /// \brief Note that the vtable for the given class was used at the
+ /// Note that the vtable for the given class was used at the
/// given location.
void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
bool DefinitionRequired = false);
- /// \brief Mark the exception specifications of all virtual member functions
+ /// Mark the exception specifications of all virtual member functions
/// in the given class as needed.
void MarkVirtualMemberExceptionSpecsNeeded(SourceLocation Loc,
const CXXRecordDecl *RD);
@@ -5759,7 +5839,7 @@ public:
void MarkVirtualMembersReferenced(SourceLocation Loc,
const CXXRecordDecl *RD);
- /// \brief Define all of the vtables that have been used in this
+ /// Define all of the vtables that have been used in this
/// translation unit and reference any virtual members used by those
/// vtables.
///
@@ -5773,10 +5853,11 @@ public:
ArrayRef<CXXCtorInitializer*> MemInits,
bool AnyErrors);
- /// \brief Check class-level dllimport/dllexport attribute. The caller must
+ /// Check class-level dllimport/dllexport attribute. The caller must
/// ensure that referenceDLLExportedClassMethods is called some point later
/// when all outer classes of Class are complete.
void checkClassLevelDLLAttribute(CXXRecordDecl *Class);
+ void checkClassLevelCodeSegAttribute(CXXRecordDecl *Class);
void referenceDLLExportedClassMethods();
@@ -5786,11 +5867,15 @@ public:
SourceLocation BaseLoc);
void CheckCompletedCXXClass(CXXRecordDecl *Record);
- void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
- Decl *TagDecl,
- SourceLocation LBrac,
+
+ /// Check that the C++ class annoated with "trivial_abi" satisfies all the
+ /// conditions that are needed for the attribute to have an effect.
+ void checkIllFormedTrivialABIStruct(CXXRecordDecl &RD);
+
+ void ActOnFinishCXXMemberSpecification(Scope *S, SourceLocation RLoc,
+ Decl *TagDecl, SourceLocation LBrac,
SourceLocation RBrac,
- AttributeList *AttrList);
+ const ParsedAttributesView &AttrList);
void ActOnFinishCXXMemberDecls();
void ActOnFinishCXXNonNestedClass(Decl *D);
@@ -5984,7 +6069,7 @@ public:
void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
- /// \brief When true, access checking violations are treated as SFINAE
+ /// When true, access checking violations are treated as SFINAE
/// failures rather than hard errors.
bool AccessCheckingSFINAE;
@@ -6027,14 +6112,15 @@ public:
bool hasAnyAcceptableTemplateNames(LookupResult &R,
bool AllowFunctionTemplates = true);
- void LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
+ bool LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
QualType ObjectType, bool EnteringContext,
- bool &MemberOfUnknownSpecialization);
+ bool &MemberOfUnknownSpecialization,
+ SourceLocation TemplateKWLoc = SourceLocation());
TemplateNameKind isTemplateName(Scope *S,
CXXScopeSpec &SS,
bool hasTemplateKeyword,
- UnqualifiedId &Name,
+ const UnqualifiedId &Name,
ParsedType ObjectType,
bool EnteringContext,
TemplateTy &Template,
@@ -6102,7 +6188,7 @@ public:
SourceLocation RAngleLoc,
Expr *RequiresClause);
- /// \brief The context in which we are checking a template parameter list.
+ /// The context in which we are checking a template parameter list.
enum TemplateParamListContext {
TPC_ClassTemplate,
TPC_VarTemplate,
@@ -6123,17 +6209,14 @@ public:
ArrayRef<TemplateParameterList *> ParamLists,
bool IsFriend, bool &IsMemberSpecialization, bool &Invalid);
- DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc, CXXScopeSpec &SS,
- IdentifierInfo *Name, SourceLocation NameLoc,
- AttributeList *Attr,
- TemplateParameterList *TemplateParams,
- AccessSpecifier AS,
- SourceLocation ModulePrivateLoc,
- SourceLocation FriendLoc,
- unsigned NumOuterTemplateParamLists,
- TemplateParameterList **OuterTemplateParamLists,
- SkipBodyInfo *SkipBody = nullptr);
+ DeclResult CheckClassTemplate(
+ Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
+ CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc,
+ const ParsedAttributesView &Attr, TemplateParameterList *TemplateParams,
+ AccessSpecifier AS, SourceLocation ModulePrivateLoc,
+ SourceLocation FriendLoc, unsigned NumOuterTemplateParamLists,
+ TemplateParameterList **OuterTemplateParamLists,
+ SkipBodyInfo *SkipBody = nullptr);
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg,
QualType NTTPType,
@@ -6142,6 +6225,8 @@ public:
void translateTemplateArguments(const ASTTemplateArgsPtr &In,
TemplateArgumentListInfo &Out);
+ ParsedTemplateArgument ActOnTemplateTypeArgument(TypeResult ParsedType);
+
void NoteAllFoundTemplates(TemplateName Name);
QualType CheckTemplateIdType(TemplateName Template,
@@ -6158,7 +6243,7 @@ public:
bool IsCtorOrDtorName = false,
bool IsClassName = false);
- /// \brief Parsed an elaborated-type-specifier that refers to a template-id,
+ /// Parsed an elaborated-type-specifier that refers to a template-id,
/// such as \c class T::template apply<U>.
TypeResult ActOnTagTemplateIdType(TagUseKind TUK,
TypeSpecifierType TagSpec,
@@ -6187,6 +6272,8 @@ public:
SourceLocation TemplateLoc,
const TemplateArgumentListInfo *TemplateArgs);
+ void diagnoseMissingTemplateArguments(TemplateName Name, SourceLocation Loc);
+
ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
LookupResult &R,
@@ -6200,17 +6287,15 @@ public:
TemplateNameKind ActOnDependentTemplateName(
Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
- UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext,
+ const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext,
TemplateTy &Template, bool AllowInjectedClassName = false);
- DeclResult
- ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc,
- SourceLocation ModulePrivateLoc,
- TemplateIdAnnotation &TemplateId,
- AttributeList *Attr,
- MultiTemplateParamsArg TemplateParameterLists,
- SkipBodyInfo *SkipBody = nullptr);
+ DeclResult ActOnClassTemplateSpecialization(
+ Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
+ SourceLocation ModulePrivateLoc, TemplateIdAnnotation &TemplateId,
+ const ParsedAttributesView &Attr,
+ MultiTemplateParamsArg TemplateParameterLists,
+ SkipBodyInfo *SkipBody = nullptr);
bool CheckTemplatePartialSpecializationArgs(SourceLocation Loc,
TemplateDecl *PrimaryTemplate,
@@ -6243,30 +6328,19 @@ public:
bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
void CompleteMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
- DeclResult
- ActOnExplicitInstantiation(Scope *S,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- unsigned TagSpec,
- SourceLocation KWLoc,
- const CXXScopeSpec &SS,
- TemplateTy Template,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation RAngleLoc,
- AttributeList *Attr);
+ DeclResult ActOnExplicitInstantiation(
+ Scope *S, SourceLocation ExternLoc, SourceLocation TemplateLoc,
+ unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS,
+ TemplateTy Template, SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation RAngleLoc, const ParsedAttributesView &Attr);
- DeclResult
- ActOnExplicitInstantiation(Scope *S,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- unsigned TagSpec,
- SourceLocation KWLoc,
- CXXScopeSpec &SS,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- AttributeList *Attr);
+ DeclResult ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc,
+ SourceLocation TemplateLoc,
+ unsigned TagSpec, SourceLocation KWLoc,
+ CXXScopeSpec &SS, IdentifierInfo *Name,
+ SourceLocation NameLoc,
+ const ParsedAttributesView &Attr);
DeclResult ActOnExplicitInstantiation(Scope *S,
SourceLocation ExternLoc,
@@ -6282,18 +6356,18 @@ public:
&Converted,
bool &HasDefaultArg);
- /// \brief Specifies the context in which a particular template
+ /// Specifies the context in which a particular template
/// argument is being checked.
enum CheckTemplateArgumentKind {
- /// \brief The template argument was specified in the code or was
+ /// The template argument was specified in the code or was
/// instantiated with some deduced template arguments.
CTAK_Specified,
- /// \brief The template argument was deduced via template argument
+ /// The template argument was deduced via template argument
/// deduction.
CTAK_Deduced,
- /// \brief The template argument was deduced from an array bound
+ /// The template argument was deduced from an array bound
/// via template argument deduction.
CTAK_DeducedFromArrayBound
};
@@ -6307,7 +6381,7 @@ public:
SmallVectorImpl<TemplateArgument> &Converted,
CheckTemplateArgumentKind CTAK = CTAK_Specified);
- /// \brief Check that the given template arguments can be be provided to
+ /// Check that the given template arguments can be be provided to
/// the given template, converting the arguments along the way.
///
/// \param Template The template to which the template arguments are being
@@ -6349,9 +6423,8 @@ public:
QualType InstantiatedParamType, Expr *Arg,
TemplateArgument &Converted,
CheckTemplateArgumentKind CTAK = CTAK_Specified);
- bool CheckTemplateArgument(TemplateTemplateParmDecl *Param,
- TemplateArgumentLoc &Arg,
- unsigned ArgumentPackIndex);
+ bool CheckTemplateTemplateArgument(TemplateParameterList *Params,
+ TemplateArgumentLoc &Arg);
ExprResult
BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
@@ -6361,10 +6434,10 @@ public:
BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
SourceLocation Loc);
- /// \brief Enumeration describing how template parameter lists are compared
+ /// Enumeration describing how template parameter lists are compared
/// for equality.
enum TemplateParameterListEqualKind {
- /// \brief We are matching the template parameter lists of two templates
+ /// We are matching the template parameter lists of two templates
/// that might be redeclarations.
///
/// \code
@@ -6373,7 +6446,7 @@ public:
/// \endcode
TPL_TemplateMatch,
- /// \brief We are matching the template parameter lists of two template
+ /// We are matching the template parameter lists of two template
/// template parameters as part of matching the template parameter lists
/// of two templates that might be redeclarations.
///
@@ -6383,7 +6456,7 @@ public:
/// \endcode
TPL_TemplateTemplateParmMatch,
- /// \brief We are matching the template parameter lists of a template
+ /// We are matching the template parameter lists of a template
/// template argument against the template parameter lists of a template
/// template parameter.
///
@@ -6404,7 +6477,7 @@ public:
bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams);
- /// \brief Called when the parser has parsed a C++ typename
+ /// Called when the parser has parsed a C++ typename
/// specifier, e.g., "typename T::type".
///
/// \param S The scope in which this typename type occurs.
@@ -6417,7 +6490,7 @@ public:
const CXXScopeSpec &SS, const IdentifierInfo &II,
SourceLocation IdLoc);
- /// \brief Called when the parser has parsed a C++ typename
+ /// Called when the parser has parsed a C++ typename
/// specifier that ends in a template-id, e.g.,
/// "typename MetaFun::template apply<T1, T2>".
///
@@ -6474,74 +6547,74 @@ public:
/// location. Useful for error recovery.
bool isUnexpandedParameterPackPermitted();
- /// \brief The context in which an unexpanded parameter pack is
+ /// The context in which an unexpanded parameter pack is
/// being diagnosed.
///
/// Note that the values of this enumeration line up with the first
/// argument to the \c err_unexpanded_parameter_pack diagnostic.
enum UnexpandedParameterPackContext {
- /// \brief An arbitrary expression.
+ /// An arbitrary expression.
UPPC_Expression = 0,
- /// \brief The base type of a class type.
+ /// The base type of a class type.
UPPC_BaseType,
- /// \brief The type of an arbitrary declaration.
+ /// The type of an arbitrary declaration.
UPPC_DeclarationType,
- /// \brief The type of a data member.
+ /// The type of a data member.
UPPC_DataMemberType,
- /// \brief The size of a bit-field.
+ /// The size of a bit-field.
UPPC_BitFieldWidth,
- /// \brief The expression in a static assertion.
+ /// The expression in a static assertion.
UPPC_StaticAssertExpression,
- /// \brief The fixed underlying type of an enumeration.
+ /// The fixed underlying type of an enumeration.
UPPC_FixedUnderlyingType,
- /// \brief The enumerator value.
+ /// The enumerator value.
UPPC_EnumeratorValue,
- /// \brief A using declaration.
+ /// A using declaration.
UPPC_UsingDeclaration,
- /// \brief A friend declaration.
+ /// A friend declaration.
UPPC_FriendDeclaration,
- /// \brief A declaration qualifier.
+ /// A declaration qualifier.
UPPC_DeclarationQualifier,
- /// \brief An initializer.
+ /// An initializer.
UPPC_Initializer,
- /// \brief A default argument.
+ /// A default argument.
UPPC_DefaultArgument,
- /// \brief The type of a non-type template parameter.
+ /// The type of a non-type template parameter.
UPPC_NonTypeTemplateParameterType,
- /// \brief The type of an exception.
+ /// The type of an exception.
UPPC_ExceptionType,
- /// \brief Partial specialization.
+ /// Partial specialization.
UPPC_PartialSpecialization,
- /// \brief Microsoft __if_exists.
+ /// Microsoft __if_exists.
UPPC_IfExists,
- /// \brief Microsoft __if_not_exists.
+ /// Microsoft __if_not_exists.
UPPC_IfNotExists,
- /// \brief Lambda expression.
+ /// Lambda expression.
UPPC_Lambda,
- /// \brief Block expression,
+ /// Block expression,
UPPC_Block
};
- /// \brief Diagnose unexpanded parameter packs.
+ /// Diagnose unexpanded parameter packs.
///
/// \param Loc The location at which we should emit the diagnostic.
///
@@ -6555,7 +6628,7 @@ public:
UnexpandedParameterPackContext UPPC,
ArrayRef<UnexpandedParameterPack> Unexpanded);
- /// \brief If the given type contains an unexpanded parameter pack,
+ /// If the given type contains an unexpanded parameter pack,
/// diagnose the error.
///
/// \param Loc The source location where a diagnostc should be emitted.
@@ -6567,7 +6640,7 @@ public:
bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T,
UnexpandedParameterPackContext UPPC);
- /// \brief If the given expression contains an unexpanded parameter
+ /// If the given expression contains an unexpanded parameter
/// pack, diagnose the error.
///
/// \param E The expression that is being checked for unexpanded
@@ -6577,7 +6650,7 @@ public:
bool DiagnoseUnexpandedParameterPack(Expr *E,
UnexpandedParameterPackContext UPPC = UPPC_Expression);
- /// \brief If the given nested-name-specifier contains an unexpanded
+ /// If the given nested-name-specifier contains an unexpanded
/// parameter pack, diagnose the error.
///
/// \param SS The nested-name-specifier that is being checked for
@@ -6587,7 +6660,7 @@ public:
bool DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
UnexpandedParameterPackContext UPPC);
- /// \brief If the given name contains an unexpanded parameter pack,
+ /// If the given name contains an unexpanded parameter pack,
/// diagnose the error.
///
/// \param NameInfo The name (with source location information) that
@@ -6597,7 +6670,7 @@ public:
bool DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
UnexpandedParameterPackContext UPPC);
- /// \brief If the given template name contains an unexpanded parameter pack,
+ /// If the given template name contains an unexpanded parameter pack,
/// diagnose the error.
///
/// \param Loc The location of the template name.
@@ -6610,7 +6683,7 @@ public:
TemplateName Template,
UnexpandedParameterPackContext UPPC);
- /// \brief If the given template argument contains an unexpanded parameter
+ /// If the given template argument contains an unexpanded parameter
/// pack, diagnose the error.
///
/// \param Arg The template argument that is being checked for unexpanded
@@ -6620,7 +6693,7 @@ public:
bool DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
UnexpandedParameterPackContext UPPC);
- /// \brief Collect the set of unexpanded parameter packs within the given
+ /// Collect the set of unexpanded parameter packs within the given
/// template argument.
///
/// \param Arg The template argument that will be traversed to find
@@ -6628,7 +6701,7 @@ public:
void collectUnexpandedParameterPacks(TemplateArgument Arg,
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
- /// \brief Collect the set of unexpanded parameter packs within the given
+ /// Collect the set of unexpanded parameter packs within the given
/// template argument.
///
/// \param Arg The template argument that will be traversed to find
@@ -6636,7 +6709,7 @@ public:
void collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
- /// \brief Collect the set of unexpanded parameter packs within the given
+ /// Collect the set of unexpanded parameter packs within the given
/// type.
///
/// \param T The type that will be traversed to find
@@ -6644,7 +6717,7 @@ public:
void collectUnexpandedParameterPacks(QualType T,
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
- /// \brief Collect the set of unexpanded parameter packs within the given
+ /// Collect the set of unexpanded parameter packs within the given
/// type.
///
/// \param TL The type that will be traversed to find
@@ -6652,7 +6725,7 @@ public:
void collectUnexpandedParameterPacks(TypeLoc TL,
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
- /// \brief Collect the set of unexpanded parameter packs within the given
+ /// Collect the set of unexpanded parameter packs within the given
/// nested-name-specifier.
///
/// \param NNS The nested-name-specifier that will be traversed to find
@@ -6660,7 +6733,7 @@ public:
void collectUnexpandedParameterPacks(NestedNameSpecifierLoc NNS,
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
- /// \brief Collect the set of unexpanded parameter packs within the given
+ /// Collect the set of unexpanded parameter packs within the given
/// name.
///
/// \param NameInfo The name that will be traversed to find
@@ -6668,7 +6741,7 @@ public:
void collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo,
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
- /// \brief Invoked when parsing a template argument followed by an
+ /// Invoked when parsing a template argument followed by an
/// ellipsis, which creates a pack expansion.
///
/// \param Arg The template argument preceding the ellipsis, which
@@ -6678,7 +6751,7 @@ public:
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg,
SourceLocation EllipsisLoc);
- /// \brief Invoked when parsing a type followed by an ellipsis, which
+ /// Invoked when parsing a type followed by an ellipsis, which
/// creates a pack expansion.
///
/// \param Type The type preceding the ellipsis, which will become
@@ -6687,20 +6760,20 @@ public:
/// \param EllipsisLoc The location of the ellipsis.
TypeResult ActOnPackExpansion(ParsedType Type, SourceLocation EllipsisLoc);
- /// \brief Construct a pack expansion type from the pattern of the pack
+ /// Construct a pack expansion type from the pattern of the pack
/// expansion.
TypeSourceInfo *CheckPackExpansion(TypeSourceInfo *Pattern,
SourceLocation EllipsisLoc,
Optional<unsigned> NumExpansions);
- /// \brief Construct a pack expansion type from the pattern of the pack
+ /// Construct a pack expansion type from the pattern of the pack
/// expansion.
QualType CheckPackExpansion(QualType Pattern,
SourceRange PatternRange,
SourceLocation EllipsisLoc,
Optional<unsigned> NumExpansions);
- /// \brief Invoked when parsing an expression followed by an ellipsis, which
+ /// Invoked when parsing an expression followed by an ellipsis, which
/// creates a pack expansion.
///
/// \param Pattern The expression preceding the ellipsis, which will become
@@ -6709,7 +6782,7 @@ public:
/// \param EllipsisLoc The location of the ellipsis.
ExprResult ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc);
- /// \brief Invoked when parsing an expression followed by an ellipsis, which
+ /// Invoked when parsing an expression followed by an ellipsis, which
/// creates a pack expansion.
///
/// \param Pattern The expression preceding the ellipsis, which will become
@@ -6719,7 +6792,7 @@ public:
ExprResult CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
Optional<unsigned> NumExpansions);
- /// \brief Determine whether we could expand a pack expansion with the
+ /// Determine whether we could expand a pack expansion with the
/// given set of parameter packs into separate arguments by repeatedly
/// transforming the pattern.
///
@@ -6761,7 +6834,7 @@ public:
bool &RetainExpansion,
Optional<unsigned> &NumExpansions);
- /// \brief Determine the number of arguments in the given pack expansion
+ /// Determine the number of arguments in the given pack expansion
/// type.
///
/// This routine assumes that the number of arguments in the expansion is
@@ -6771,7 +6844,7 @@ public:
Optional<unsigned> getNumArgumentsInExpansion(QualType T,
const MultiLevelTemplateArgumentList &TemplateArgs);
- /// \brief Determine whether the given declarator contains any unexpanded
+ /// Determine whether the given declarator contains any unexpanded
/// parameter packs.
///
/// This routine is used by the parser to disambiguate function declarators
@@ -6788,7 +6861,7 @@ public:
/// false otherwise.
bool containsUnexpandedParameterPacks(Declarator &D);
- /// \brief Returns the pattern of the pack expansion for a template argument.
+ /// Returns the pattern of the pack expansion for a template argument.
///
/// \param OrigLoc The template argument to expand.
///
@@ -6820,7 +6893,7 @@ public:
QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType,
bool AdjustExceptionSpec = false);
- /// \brief Describes the result of template argument deduction.
+ /// Describes the result of template argument deduction.
///
/// The TemplateDeductionResult enumeration describes the result of
/// template argument deduction, as returned from
@@ -6830,51 +6903,54 @@ public:
/// list (if successful) or the specific template parameters or
/// deduced arguments that were involved in the failure.
enum TemplateDeductionResult {
- /// \brief Template argument deduction was successful.
+ /// Template argument deduction was successful.
TDK_Success = 0,
- /// \brief The declaration was invalid; do nothing.
+ /// The declaration was invalid; do nothing.
TDK_Invalid,
- /// \brief Template argument deduction exceeded the maximum template
+ /// Template argument deduction exceeded the maximum template
/// instantiation depth (which has already been diagnosed).
TDK_InstantiationDepth,
- /// \brief Template argument deduction did not deduce a value
+ /// Template argument deduction did not deduce a value
/// for every template parameter.
TDK_Incomplete,
- /// \brief Template argument deduction produced inconsistent
+ /// Template argument deduction did not deduce a value for every
+ /// expansion of an expanded template parameter pack.
+ TDK_IncompletePack,
+ /// Template argument deduction produced inconsistent
/// deduced values for the given template parameter.
TDK_Inconsistent,
- /// \brief Template argument deduction failed due to inconsistent
+ /// Template argument deduction failed due to inconsistent
/// cv-qualifiers on a template parameter type that would
/// otherwise be deduced, e.g., we tried to deduce T in "const T"
/// but were given a non-const "X".
TDK_Underqualified,
- /// \brief Substitution of the deduced template argument values
+ /// Substitution of the deduced template argument values
/// resulted in an error.
TDK_SubstitutionFailure,
- /// \brief After substituting deduced template arguments, a dependent
+ /// After substituting deduced template arguments, a dependent
/// parameter type did not match the corresponding argument.
TDK_DeducedMismatch,
- /// \brief After substituting deduced template arguments, an element of
+ /// After substituting deduced template arguments, an element of
/// a dependent parameter type did not match the corresponding element
/// of the corresponding argument (when deducing from an initializer list).
TDK_DeducedMismatchNested,
- /// \brief A non-depnedent component of the parameter did not match the
+ /// A non-depnedent component of the parameter did not match the
/// corresponding component of the argument.
TDK_NonDeducedMismatch,
- /// \brief When performing template argument deduction for a function
+ /// When performing template argument deduction for a function
/// template, there were too many call arguments.
TDK_TooManyArguments,
- /// \brief When performing template argument deduction for a function
+ /// When performing template argument deduction for a function
/// template, there were too few call arguments.
TDK_TooFewArguments,
- /// \brief The explicitly-specified template arguments were not valid
+ /// The explicitly-specified template arguments were not valid
/// template arguments for the given template.
TDK_InvalidExplicitArguments,
- /// \brief Checking non-dependent argument conversions failed.
+ /// Checking non-dependent argument conversions failed.
TDK_NonDependentConversionFailure,
- /// \brief Deduction failed; that's all we know.
+ /// Deduction failed; that's all we know.
TDK_MiscellaneousDeductionFailure,
- /// \brief CUDA Target attributes do not match.
+ /// CUDA Target attributes do not match.
TDK_CUDATargetMismatch
};
@@ -6947,16 +7023,16 @@ public:
sema::TemplateDeductionInfo &Info,
bool IsAddressOfFunction = false);
- /// \brief Substitute Replacement for \p auto in \p TypeWithAuto
+ /// Substitute Replacement for \p auto in \p TypeWithAuto
QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement);
- /// \brief Substitute Replacement for auto in TypeWithAuto
+ /// Substitute Replacement for auto in TypeWithAuto
TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
QualType Replacement);
- /// \brief Completely replace the \c auto in \p TypeWithAuto by
+ /// Completely replace the \c auto in \p TypeWithAuto by
/// \p Replacement. This does not retain any \c auto type sugar.
QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement);
- /// \brief Result type of DeduceAutoType.
+ /// Result type of DeduceAutoType.
enum DeduceAutoResult {
DAR_Succeeded,
DAR_Failed,
@@ -6973,7 +7049,7 @@ public:
bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
bool Diagnose = true);
- /// \brief Declare implicit deduction guides for a class template if we've
+ /// Declare implicit deduction guides for a class template if we've
/// not already done so.
void DeclareImplicitDeductionGuides(TemplateDecl *Template,
SourceLocation Loc);
@@ -7054,7 +7130,7 @@ public:
/// alone is not sufficient to identify the context). This covers template
/// instantiation and various forms of implicitly-generated functions.
struct CodeSynthesisContext {
- /// \brief The kind of template instantiation we are performing
+ /// The kind of template instantiation we are performing
enum SynthesisKind {
/// We are instantiating a template declaration. The entity is
/// the declaration we're instantiating (e.g., a CXXRecordDecl).
@@ -7102,33 +7178,39 @@ public:
/// We are defining a synthesized function (such as a defaulted special
/// member).
DefiningSynthesizedFunction,
+
+ /// Added for Template instantiation observation.
+ /// Memoization means we are _not_ instantiating a template because
+ /// it is already instantiated (but we entered a context where we
+ /// would have had to if it was not already instantiated).
+ Memoization
} Kind;
- /// \brief Was the enclosing context a non-instantiation SFINAE context?
+ /// Was the enclosing context a non-instantiation SFINAE context?
bool SavedInNonInstantiationSFINAEContext;
- /// \brief The point of instantiation or synthesis within the source code.
+ /// The point of instantiation or synthesis within the source code.
SourceLocation PointOfInstantiation;
- /// \brief The entity that is being synthesized.
+ /// The entity that is being synthesized.
Decl *Entity;
- /// \brief The template (or partial specialization) in which we are
+ /// The template (or partial specialization) in which we are
/// performing the instantiation, for substitutions of prior template
/// arguments.
NamedDecl *Template;
- /// \brief The list of template arguments we are substituting, if they
+ /// The list of template arguments we are substituting, if they
/// are not part of the entity.
const TemplateArgument *TemplateArgs;
// FIXME: Wrap this union around more members, or perhaps store the
// kind-specific members in the RAII object owning the context.
union {
- /// \brief The number of template arguments in TemplateArgs.
+ /// The number of template arguments in TemplateArgs.
unsigned NumTemplateArgs;
- /// \brief The special member being declared or defined.
+ /// The special member being declared or defined.
CXXSpecialMember SpecialMember;
};
@@ -7137,11 +7219,11 @@ public:
return {TemplateArgs, NumTemplateArgs};
}
- /// \brief The template deduction info object associated with the
+ /// The template deduction info object associated with the
/// substitution or checking of explicit or deduced template arguments.
sema::TemplateDeductionInfo *DeductionInfo;
- /// \brief The source range that covers the construct that cause
+ /// The source range that covers the construct that cause
/// the instantiation, e.g., the template-id that causes a class
/// template instantiation.
SourceRange InstantiationRange;
@@ -7150,12 +7232,12 @@ public:
: Kind(TemplateInstantiation), Entity(nullptr), Template(nullptr),
TemplateArgs(nullptr), NumTemplateArgs(0), DeductionInfo(nullptr) {}
- /// \brief Determines whether this template is an actual instantiation
+ /// Determines whether this template is an actual instantiation
/// that should be counted toward the maximum instantiation depth.
bool isInstantiationRecord() const;
};
- /// \brief List of active code synthesis contexts.
+ /// List of active code synthesis contexts.
///
/// This vector is treated as a stack. As synthesis of one entity requires
/// synthesis of another, additional contexts are pushed onto the stack.
@@ -7168,32 +7250,32 @@ public:
/// by some template instantiation.
llvm::DenseSet<QualType> InstantiatedNonDependentTypes;
- /// \brief Extra modules inspected when performing a lookup during a template
+ /// Extra modules inspected when performing a lookup during a template
/// instantiation. Computed lazily.
SmallVector<Module*, 16> CodeSynthesisContextLookupModules;
- /// \brief Cache of additional modules that should be used for name lookup
+ /// Cache of additional modules that should be used for name lookup
/// within the current template instantiation. Computed lazily; use
/// getLookupModules() to get a complete set.
llvm::DenseSet<Module*> LookupModulesCache;
- /// \brief Get the set of additional modules that should be checked during
+ /// Get the set of additional modules that should be checked during
/// name lookup. A module and its imports become visible when instanting a
/// template defined within it.
llvm::DenseSet<Module*> &getLookupModules();
- /// \brief Map from the most recent declaration of a namespace to the most
+ /// Map from the most recent declaration of a namespace to the most
/// recent visible declaration of that namespace.
llvm::DenseMap<NamedDecl*, NamedDecl*> VisibleNamespaceCache;
- /// \brief Whether we are in a SFINAE context that is not associated with
+ /// Whether we are in a SFINAE context that is not associated with
/// template instantiation.
///
/// This is used when setting up a SFINAE trap (\c see SFINAETrap) outside
/// of a template instantiation or template argument deduction.
bool InNonInstantiationSFINAEContext;
- /// \brief The number of \p CodeSynthesisContexts that are not template
+ /// The number of \p CodeSynthesisContexts that are not template
/// instantiations and, therefore, should not be counted as part of the
/// instantiation depth.
///
@@ -7202,7 +7284,7 @@ public:
// FIXME: Should we have a similar limit for other forms of synthesis?
unsigned NonInstantiationEntries;
- /// \brief The depth of the context stack at the point when the most recent
+ /// The depth of the context stack at the point when the most recent
/// error or warning was produced.
///
/// This value is used to suppress printing of redundant context stacks
@@ -7210,7 +7292,15 @@ public:
// FIXME: Does this belong in Sema? It's tough to implement it anywhere else.
unsigned LastEmittedCodeSynthesisContextDepth = 0;
- /// \brief The current index into pack expansion arguments that will be
+ /// The template instantiation callbacks to trace or track
+ /// instantiations (objects can be chained).
+ ///
+ /// This callbacks is used to print, trace or track template
+ /// instantiations as they are being constructed.
+ std::vector<std::unique_ptr<TemplateInstantiationCallback>>
+ TemplateInstCallbacks;
+
+ /// The current index into pack expansion arguments that will be
/// used for substitution of parameter packs.
///
/// The pack expansion index will be -1 to indicate that parameter packs
@@ -7218,7 +7308,7 @@ public:
/// which argument within the parameter pack will be used for substitution.
int ArgumentPackSubstitutionIndex;
- /// \brief RAII object used to change the argument pack substitution index
+ /// RAII object used to change the argument pack substitution index
/// within a \c Sema object.
///
/// See \c ArgumentPackSubstitutionIndex for more information.
@@ -7239,7 +7329,7 @@ public:
friend class ArgumentPackSubstitutionRAII;
- /// \brief For each declaration that involved template argument deduction, the
+ /// For each declaration that involved template argument deduction, the
/// set of diagnostics that were suppressed during that template argument
/// deduction.
///
@@ -7248,7 +7338,7 @@ public:
SuppressedDiagnosticsMap;
SuppressedDiagnosticsMap SuppressedDiagnostics;
- /// \brief A stack object to be created when performing template
+ /// A stack object to be created when performing template
/// instantiation.
///
/// Construction of an object of type \c InstantiatingTemplate
@@ -7260,7 +7350,7 @@ public:
/// Destruction of this object will pop the named instantiation off
/// the stack.
struct InstantiatingTemplate {
- /// \brief Note that we are instantiating a class template,
+ /// Note that we are instantiating a class template,
/// function template, variable template, alias template,
/// or a member thereof.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
@@ -7268,20 +7358,20 @@ public:
SourceRange InstantiationRange = SourceRange());
struct ExceptionSpecification {};
- /// \brief Note that we are instantiating an exception specification
+ /// Note that we are instantiating an exception specification
/// of a function template.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
FunctionDecl *Entity, ExceptionSpecification,
SourceRange InstantiationRange = SourceRange());
- /// \brief Note that we are instantiating a default argument in a
+ /// Note that we are instantiating a default argument in a
/// template-id.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
TemplateParameter Param, TemplateDecl *Template,
ArrayRef<TemplateArgument> TemplateArgs,
SourceRange InstantiationRange = SourceRange());
- /// \brief Note that we are substituting either explicitly-specified or
+ /// Note that we are substituting either explicitly-specified or
/// deduced template arguments during function template argument deduction.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
FunctionTemplateDecl *FunctionTemplate,
@@ -7290,7 +7380,7 @@ public:
sema::TemplateDeductionInfo &DeductionInfo,
SourceRange InstantiationRange = SourceRange());
- /// \brief Note that we are instantiating as part of template
+ /// Note that we are instantiating as part of template
/// argument deduction for a class template declaration.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
TemplateDecl *Template,
@@ -7298,7 +7388,7 @@ public:
sema::TemplateDeductionInfo &DeductionInfo,
SourceRange InstantiationRange = SourceRange());
- /// \brief Note that we are instantiating as part of template
+ /// Note that we are instantiating as part of template
/// argument deduction for a class template partial
/// specialization.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
@@ -7307,7 +7397,7 @@ public:
sema::TemplateDeductionInfo &DeductionInfo,
SourceRange InstantiationRange = SourceRange());
- /// \brief Note that we are instantiating as part of template
+ /// Note that we are instantiating as part of template
/// argument deduction for a variable template partial
/// specialization.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
@@ -7316,14 +7406,14 @@ public:
sema::TemplateDeductionInfo &DeductionInfo,
SourceRange InstantiationRange = SourceRange());
- /// \brief Note that we are instantiating a default argument for a function
+ /// Note that we are instantiating a default argument for a function
/// parameter.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
ParmVarDecl *Param,
ArrayRef<TemplateArgument> TemplateArgs,
SourceRange InstantiationRange = SourceRange());
- /// \brief Note that we are substituting prior template arguments into a
+ /// Note that we are substituting prior template arguments into a
/// non-type parameter.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
NamedDecl *Template,
@@ -7331,7 +7421,7 @@ public:
ArrayRef<TemplateArgument> TemplateArgs,
SourceRange InstantiationRange);
- /// \brief Note that we are substituting prior template arguments into a
+ /// Note that we are substituting prior template arguments into a
/// template template parameter.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
NamedDecl *Template,
@@ -7339,7 +7429,7 @@ public:
ArrayRef<TemplateArgument> TemplateArgs,
SourceRange InstantiationRange);
- /// \brief Note that we are checking the default template argument
+ /// Note that we are checking the default template argument
/// against the template parameter for a given template-id.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
TemplateDecl *Template,
@@ -7348,16 +7438,16 @@ public:
SourceRange InstantiationRange);
- /// \brief Note that we have finished instantiating this template.
+ /// Note that we have finished instantiating this template.
void Clear();
~InstantiatingTemplate() { Clear(); }
- /// \brief Determines whether we have exceeded the maximum
+ /// Determines whether we have exceeded the maximum
/// recursive template instantiations.
bool isInvalid() const { return Invalid; }
- /// \brief Determine whether we are already instantiating this
+ /// Determine whether we are already instantiating this
/// specialization in some surrounding active instantiation.
bool isAlreadyInstantiating() const { return AlreadyInstantiating; }
@@ -7402,7 +7492,7 @@ public:
void PrintPragmaAttributeInstantiationPoint();
- /// \brief Determines whether we are currently in a context where
+ /// Determines whether we are currently in a context where
/// template argument substitution failures are not considered
/// errors.
///
@@ -7412,7 +7502,7 @@ public:
/// diagnostics that will be suppressed.
Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const;
- /// \brief Determines whether we are currently in a context that
+ /// Determines whether we are currently in a context that
/// is not evaluated as per C++ [expr] p5.
bool isUnevaluatedContext() const {
assert(!ExprEvalContexts.empty() &&
@@ -7420,7 +7510,7 @@ public:
return ExprEvalContexts.back().isUnevaluated();
}
- /// \brief RAII class used to determine whether SFINAE has
+ /// RAII class used to determine whether SFINAE has
/// trapped any errors that occur during template argument
/// deduction.
class SFINAETrap {
@@ -7453,13 +7543,13 @@ public:
PrevLastDiagnosticIgnored);
}
- /// \brief Determine whether any SFINAE errors have been trapped.
+ /// Determine whether any SFINAE errors have been trapped.
bool hasErrorOccurred() const {
return SemaRef.NumSFINAEErrors > PrevSFINAEErrors;
}
};
- /// \brief RAII class used to indicate that we are performing provisional
+ /// RAII class used to indicate that we are performing provisional
/// semantic analysis to determine the validity of a construct, so
/// typo-correction and diagnostics in the immediate context (not within
/// implicitly-instantiated templates) should be suppressed.
@@ -7479,30 +7569,30 @@ public:
}
};
- /// \brief The current instantiation scope used to store local
+ /// The current instantiation scope used to store local
/// variables.
LocalInstantiationScope *CurrentInstantiationScope;
- /// \brief Tracks whether we are in a context where typo correction is
+ /// Tracks whether we are in a context where typo correction is
/// disabled.
bool DisableTypoCorrection;
- /// \brief The number of typos corrected by CorrectTypo.
+ /// The number of typos corrected by CorrectTypo.
unsigned TyposCorrected;
typedef llvm::SmallSet<SourceLocation, 2> SrcLocSet;
typedef llvm::DenseMap<IdentifierInfo *, SrcLocSet> IdentifierSourceLocations;
- /// \brief A cache containing identifiers for which typo correction failed and
+ /// A cache containing identifiers for which typo correction failed and
/// their locations, so that repeated attempts to correct an identifier in a
/// given location are ignored if typo correction already failed for it.
IdentifierSourceLocations TypoCorrectionFailures;
- /// \brief Worker object for performing CFG-based warnings.
+ /// Worker object for performing CFG-based warnings.
sema::AnalysisBasedWarnings AnalysisWarnings;
threadSafety::BeforeSet *ThreadSafetyDeclCache;
- /// \brief An entity for which implicit template instantiation is required.
+ /// An entity for which implicit template instantiation is required.
///
/// The source location associated with the declaration is the first place in
/// the source code where the declaration was "used". It is not necessarily
@@ -7512,10 +7602,14 @@ public:
/// because users will need to know what code triggered the instantiation.
typedef std::pair<ValueDecl *, SourceLocation> PendingImplicitInstantiation;
- /// \brief The queue of implicit template instantiations that are required
+ /// The queue of implicit template instantiations that are required
/// but have not yet been performed.
std::deque<PendingImplicitInstantiation> PendingInstantiations;
+ /// Queue of implicit template instantiations that cannot be performed
+ /// eagerly.
+ SmallVector<PendingImplicitInstantiation, 1> LateParsedInstantiations;
+
class GlobalEagerInstantiationScope {
public:
GlobalEagerInstantiationScope(Sema &S, bool Enabled)
@@ -7554,7 +7648,7 @@ public:
bool Enabled;
};
- /// \brief The queue of implicit template instantiations that are required
+ /// The queue of implicit template instantiations that are required
/// and must be performed within the current local scope.
///
/// This queue is only used for member functions of local classes in
@@ -7653,7 +7747,7 @@ public:
ExprResult SubstExpr(Expr *E,
const MultiLevelTemplateArgumentList &TemplateArgs);
- /// \brief Substitute the given template arguments into a list of
+ /// Substitute the given template arguments into a list of
/// expressions, expanding pack expansions if required.
///
/// \param Exprs The list of expressions to substitute into.
@@ -7673,6 +7767,10 @@ public:
StmtResult SubstStmt(Stmt *S,
const MultiLevelTemplateArgumentList &TemplateArgs);
+ TemplateParameterList *
+ SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
+
Decl *SubstDecl(Decl *D, DeclContext *Owner,
const MultiLevelTemplateArgumentList &TemplateArgs);
@@ -7760,6 +7858,9 @@ public:
void InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
FunctionDecl *Function);
+ FunctionDecl *InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD,
+ const TemplateArgumentList *Args,
+ SourceLocation Loc);
void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
FunctionDecl *Function,
bool Recursive = false,
@@ -7827,20 +7928,14 @@ public:
SourceLocation rAngleLoc);
void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList);
- Decl *ActOnStartClassInterface(Scope *S,
- SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- ObjCTypeParamList *typeParamList,
- IdentifierInfo *SuperName,
- SourceLocation SuperLoc,
- ArrayRef<ParsedType> SuperTypeArgs,
- SourceRange SuperTypeArgsRange,
- Decl * const *ProtoRefs,
- unsigned NumProtoRefs,
- const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList);
+ Decl *ActOnStartClassInterface(
+ Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName,
+ SourceLocation ClassLoc, ObjCTypeParamList *typeParamList,
+ IdentifierInfo *SuperName, SourceLocation SuperLoc,
+ ArrayRef<ParsedType> SuperTypeArgs, SourceRange SuperTypeArgsRange,
+ Decl *const *ProtoRefs, unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc,
+ const ParsedAttributesView &AttrList);
void ActOnSuperClassOfClassInterface(Scope *S,
SourceLocation AtInterfaceLoc,
@@ -7868,24 +7963,18 @@ public:
const ObjCList<ObjCProtocolDecl> &PList);
Decl *ActOnStartProtocolInterface(
- SourceLocation AtProtoInterfaceLoc,
- IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
- Decl * const *ProtoRefNames, unsigned NumProtoRefs,
- const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList);
-
- Decl *ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- ObjCTypeParamList *typeParamList,
- IdentifierInfo *CategoryName,
- SourceLocation CategoryLoc,
- Decl * const *ProtoRefs,
- unsigned NumProtoRefs,
- const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList);
+ SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName,
+ SourceLocation ProtocolLoc, Decl *const *ProtoRefNames,
+ unsigned NumProtoRefs, const SourceLocation *ProtoLocs,
+ SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList);
+
+ Decl *ActOnStartCategoryInterface(
+ SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName,
+ SourceLocation ClassLoc, ObjCTypeParamList *typeParamList,
+ IdentifierInfo *CategoryName, SourceLocation CategoryLoc,
+ Decl *const *ProtoRefs, unsigned NumProtoRefs,
+ const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc,
+ const ParsedAttributesView &AttrList);
Decl *ActOnStartClassImplementation(
SourceLocation AtClassImplLoc,
@@ -7908,9 +7997,10 @@ public:
ArrayRef<ObjCTypeParamList *> TypeParamLists,
unsigned NumElts);
- DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc,
- ArrayRef<IdentifierLocPair> IdentList,
- AttributeList *attrList);
+ DeclGroupPtrTy
+ ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc,
+ ArrayRef<IdentifierLocPair> IdentList,
+ const ParsedAttributesView &attrList);
void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer,
ArrayRef<IdentifierLocPair> ProtocolId,
@@ -8045,22 +8135,21 @@ public:
ObjCDeclSpec DeclSpec;
/// ArgAttrs - Attribute list for this argument.
- AttributeList *ArgAttrs;
+ ParsedAttributesView ArgAttrs;
};
Decl *ActOnMethodDeclaration(
- Scope *S,
- SourceLocation BeginLoc, // location of the + or -.
- SourceLocation EndLoc, // location of the ; or {.
- tok::TokenKind MethodType,
- ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
- ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
- // optional arguments. The number of types/arguments is obtained
- // from the Sel.getNumArgs().
- ObjCArgInfo *ArgInfo,
- DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
- AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
- bool isVariadic, bool MethodDefinition);
+ Scope *S,
+ SourceLocation BeginLoc, // location of the + or -.
+ SourceLocation EndLoc, // location of the ; or {.
+ tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
+ ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
+ // optional arguments. The number of types/arguments is obtained
+ // from the Sel.getNumArgs().
+ ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo,
+ unsigned CNumArgs, // c-style args
+ const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodImplKind,
+ bool isVariadic, bool MethodDefinition);
ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel,
const ObjCObjectPointerType *OPT,
@@ -8088,14 +8177,14 @@ public:
ObjCMethodDecl *tryCaptureObjCSelf(SourceLocation Loc);
- /// \brief Describes the kind of message expression indicated by a message
+ /// Describes the kind of message expression indicated by a message
/// send that starts with an identifier.
enum ObjCMessageKind {
- /// \brief The message is sent to 'super'.
+ /// The message is sent to 'super'.
ObjCSuperMessage,
- /// \brief The message is an instance message.
+ /// The message is an instance message.
ObjCInstanceMessage,
- /// \brief The message is a class message, and the identifier is a type
+ /// The message is a class message, and the identifier is a type
/// name.
ObjCClassMessage
};
@@ -8204,12 +8293,12 @@ public:
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
- /// \brief Check whether the given new method is a valid override of the
+ /// Check whether the given new method is a valid override of the
/// given overridden method, and set any properties that should be inherited.
void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
const ObjCMethodDecl *Overridden);
- /// \brief Describes the compatibility of a result type with its method.
+ /// Describes the compatibility of a result type with its method.
enum ResultTypeCompatibilityKind {
RTC_Compatible,
RTC_Incompatible,
@@ -8266,7 +8355,7 @@ public:
LangOptions::PragmaMSPointersToMembersKind Kind,
SourceLocation PragmaLoc);
- /// \brief Called on well formed \#pragma vtordisp().
+ /// Called on well formed \#pragma vtordisp().
void ActOnPragmaMSVtorDisp(PragmaMsStackAction Action,
SourceLocation PragmaLoc,
MSVtorDispAttr::Mode Value);
@@ -8285,22 +8374,22 @@ public:
int SectionFlags,
SourceLocation PragmaSectionLocation);
- /// \brief Called on well formed \#pragma bss_seg/data_seg/const_seg/code_seg.
+ /// Called on well formed \#pragma bss_seg/data_seg/const_seg/code_seg.
void ActOnPragmaMSSeg(SourceLocation PragmaLocation,
PragmaMsStackAction Action,
llvm::StringRef StackSlotLabel,
StringLiteral *SegmentName,
llvm::StringRef PragmaName);
- /// \brief Called on well formed \#pragma section().
+ /// Called on well formed \#pragma section().
void ActOnPragmaMSSection(SourceLocation PragmaLocation,
int SectionFlags, StringLiteral *SegmentName);
- /// \brief Called on well-formed \#pragma init_seg().
+ /// Called on well-formed \#pragma init_seg().
void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
StringLiteral *SegmentName);
- /// \brief Called on #pragma clang __debug dump II
+ /// Called on #pragma clang __debug dump II
void ActOnPragmaDump(Scope *S, SourceLocation Loc, IdentifierInfo *II);
/// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
@@ -8376,35 +8465,34 @@ public:
/// the appropriate attribute.
void AddCFAuditedAttribute(Decl *D);
- /// \brief Called on well-formed '\#pragma clang attribute push'.
- void ActOnPragmaAttributePush(AttributeList &Attribute,
- SourceLocation PragmaLoc,
+ /// Called on well-formed '\#pragma clang attribute push'.
+ void ActOnPragmaAttributePush(ParsedAttr &Attribute, SourceLocation PragmaLoc,
attr::ParsedSubjectMatchRuleSet Rules);
- /// \brief Called on well-formed '\#pragma clang attribute pop'.
+ /// Called on well-formed '\#pragma clang attribute pop'.
void ActOnPragmaAttributePop(SourceLocation PragmaLoc);
- /// \brief Adds the attributes that have been specified using the
+ /// Adds the attributes that have been specified using the
/// '\#pragma clang attribute push' directives to the given declaration.
void AddPragmaAttributes(Scope *S, Decl *D);
void DiagnoseUnterminatedPragmaAttribute();
- /// \brief Called on well formed \#pragma clang optimize.
+ /// Called on well formed \#pragma clang optimize.
void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc);
- /// \brief Get the location for the currently active "\#pragma clang optimize
+ /// Get the location for the currently active "\#pragma clang optimize
/// off". If this location is invalid, then the state of the pragma is "on".
SourceLocation getOptimizeOffPragmaLocation() const {
return OptimizeOffPragmaLocation;
}
- /// \brief Only called on function definitions; if there is a pragma in scope
+ /// Only called on function definitions; if there is a pragma in scope
/// with the effect of a range-based optnone, consider marking the function
/// with attribute optnone.
void AddRangeBasedOptnone(FunctionDecl *FD);
- /// \brief Adds the 'optnone' attribute to the function declaration if there
+ /// Adds the 'optnone' attribute to the function declaration if there
/// are no conflicts; Loc represents the location causing the 'optnone'
/// attribute to be added (usually because of a pragma).
void AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, SourceLocation Loc);
@@ -8465,8 +8553,11 @@ public:
StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E,
bool IsImplicit = false);
StmtResult BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs);
+ bool buildCoroutineParameterMoves(SourceLocation Loc);
VarDecl *buildCoroutinePromise(SourceLocation Loc);
void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body);
+ ClassTemplateDecl *lookupCoroutineTraits(SourceLocation KwLoc,
+ SourceLocation FuncLoc);
//===--------------------------------------------------------------------===//
// OpenCL extensions.
@@ -8485,36 +8576,36 @@ public:
CurrOpenCLExtension = Ext;
}
- /// \brief Set OpenCL extensions for a type which can only be used when these
+ /// Set OpenCL extensions for a type which can only be used when these
/// OpenCL extensions are enabled. If \p Exts is empty, do nothing.
/// \param Exts A space separated list of OpenCL extensions.
void setOpenCLExtensionForType(QualType T, llvm::StringRef Exts);
- /// \brief Set OpenCL extensions for a declaration which can only be
+ /// Set OpenCL extensions for a declaration which can only be
/// used when these OpenCL extensions are enabled. If \p Exts is empty, do
/// nothing.
/// \param Exts A space separated list of OpenCL extensions.
void setOpenCLExtensionForDecl(Decl *FD, llvm::StringRef Exts);
- /// \brief Set current OpenCL extensions for a type which can only be used
+ /// Set current OpenCL extensions for a type which can only be used
/// when these OpenCL extensions are enabled. If current OpenCL extension is
/// empty, do nothing.
void setCurrentOpenCLExtensionForType(QualType T);
- /// \brief Set current OpenCL extensions for a declaration which
+ /// Set current OpenCL extensions for a declaration which
/// can only be used when these OpenCL extensions are enabled. If current
/// OpenCL extension is empty, do nothing.
void setCurrentOpenCLExtensionForDecl(Decl *FD);
bool isOpenCLDisabledDecl(Decl *FD);
- /// \brief Check if type \p T corresponding to declaration specifier \p DS
+ /// Check if type \p T corresponding to declaration specifier \p DS
/// is disabled due to required OpenCL extensions being disabled. If so,
/// emit diagnostics.
/// \return true if type is disabled.
bool checkOpenCLDisabledTypeDeclSpec(const DeclSpec &DS, QualType T);
- /// \brief Check if declaration \p D used by expression \p E
+ /// Check if declaration \p D used by expression \p E
/// is disabled due to required OpenCL extensions being disabled. If so,
/// emit diagnostics.
/// \return true if type is disabled.
@@ -8527,7 +8618,7 @@ private:
void *VarDataSharingAttributesStack;
/// Set to true inside '#pragma omp declare target' region.
bool IsInOpenMPDeclareTargetContext = false;
- /// \brief Initialization of data-sharing attributes stack.
+ /// Initialization of data-sharing attributes stack.
void InitDataSharingAttributesStack();
void DestroyDataSharingAttributesStack();
ExprResult
@@ -8562,87 +8653,86 @@ private:
SourceRange SrcRange = SourceRange());
public:
- /// \brief Return true if the provided declaration \a VD should be captured by
+ /// Return true if the provided declaration \a VD should be captured by
/// reference.
/// \param Level Relative level of nested OpenMP construct for that the check
/// is performed.
- bool IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level);
+ bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const;
- /// \brief Check if the specified variable is used in one of the private
+ /// Check if the specified variable is used in one of the private
/// clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP
/// constructs.
- VarDecl *IsOpenMPCapturedDecl(ValueDecl *D);
+ VarDecl *isOpenMPCapturedDecl(ValueDecl *D) const;
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
ExprObjectKind OK, SourceLocation Loc);
- /// \brief Check if the specified variable is used in 'private' clause.
+ /// Check if the specified variable is used in 'private' clause.
/// \param Level Relative level of nested OpenMP construct for that the check
/// is performed.
- bool isOpenMPPrivateDecl(ValueDecl *D, unsigned Level);
+ bool isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const;
/// Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.)
/// for \p FD based on DSA for the provided corresponding captured declaration
/// \p D.
- void setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level);
+ void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level);
- /// \brief Check if the specified variable is captured by 'target' directive.
+ /// Check if the specified variable is captured by 'target' directive.
/// \param Level Relative level of nested OpenMP construct for that the check
/// is performed.
- bool isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level);
+ bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level) const;
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc,
Expr *Op);
- /// \brief Called on start of new data sharing attribute block.
+ /// Called on start of new data sharing attribute block.
void StartOpenMPDSABlock(OpenMPDirectiveKind K,
const DeclarationNameInfo &DirName, Scope *CurScope,
SourceLocation Loc);
- /// \brief Start analysis of clauses.
+ /// Start analysis of clauses.
void StartOpenMPClause(OpenMPClauseKind K);
- /// \brief End analysis of clauses.
+ /// End analysis of clauses.
void EndOpenMPClause();
- /// \brief Called on end of data sharing attribute block.
+ /// Called on end of data sharing attribute block.
void EndOpenMPDSABlock(Stmt *CurDirective);
- /// \brief Check if the current region is an OpenMP loop region and if it is,
+ /// Check if the current region is an OpenMP loop region and if it is,
/// mark loop control variable, used in \p Init for loop initialization, as
/// private by default.
/// \param Init First part of the for loop.
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init);
// OpenMP directives and clauses.
- /// \brief Called on correct id-expression from the '#pragma omp
+ /// Called on correct id-expression from the '#pragma omp
/// threadprivate'.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope,
CXXScopeSpec &ScopeSpec,
const DeclarationNameInfo &Id);
- /// \brief Called on well-formed '#pragma omp threadprivate'.
+ /// Called on well-formed '#pragma omp threadprivate'.
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(
SourceLocation Loc,
ArrayRef<Expr *> VarList);
- /// \brief Builds a new OpenMPThreadPrivateDecl and checks its correctness.
- OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(
- SourceLocation Loc,
- ArrayRef<Expr *> VarList);
- /// \brief Check if the specified type is allowed to be used in 'omp declare
+ /// Builds a new OpenMPThreadPrivateDecl and checks its correctness.
+ OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(SourceLocation Loc,
+ ArrayRef<Expr *> VarList);
+ /// Check if the specified type is allowed to be used in 'omp declare
/// reduction' construct.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
TypeResult ParsedType);
- /// \brief Called on start of '#pragma omp declare reduction'.
+ /// Called on start of '#pragma omp declare reduction'.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(
Scope *S, DeclContext *DC, DeclarationName Name,
ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
AccessSpecifier AS, Decl *PrevDeclInScope = nullptr);
- /// \brief Initialize declare reduction construct initializer.
+ /// Initialize declare reduction construct initializer.
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D);
- /// \brief Finish current declare reduction construct initializer.
+ /// Finish current declare reduction construct initializer.
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner);
- /// \brief Initialize declare reduction construct initializer.
+ /// Initialize declare reduction construct initializer.
/// \return omp_priv variable.
VarDecl *ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D);
- /// \brief Finish current declare reduction construct initializer.
+ /// Finish current declare reduction construct initializer.
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
VarDecl *OmpPrivParm);
- /// \brief Called at the end of '#pragma omp declare reduction'.
+ /// Called at the end of '#pragma omp declare reduction'.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(
Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid);
@@ -8674,9 +8764,9 @@ public:
/// Return the number of captured regions created for an OpenMP directive.
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind);
- /// \brief Initialization of captured region for OpenMP region.
+ /// Initialization of captured region for OpenMP region.
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope);
- /// \brief End of OpenMP region.
+ /// End of OpenMP region.
///
/// \param S Statement associated with the current OpenMP region.
/// \param Clauses List of clauses for the current OpenMP region.
@@ -8687,230 +8777,220 @@ public:
OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp parallel' after parsing
+ /// Called on well-formed '\#pragma omp parallel' after parsing
/// of the associated statement.
StmtResult ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt,
SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp simd' after parsing
+ using VarsWithInheritedDSAType =
+ llvm::SmallDenseMap<const ValueDecl *, const Expr *, 4>;
+ /// Called on well-formed '\#pragma omp simd' after parsing
/// of the associated statement.
- StmtResult ActOnOpenMPSimdDirective(
- ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp for' after parsing
+ StmtResult
+ ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
+ SourceLocation StartLoc, SourceLocation EndLoc,
+ VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp for' after parsing
/// of the associated statement.
- StmtResult ActOnOpenMPForDirective(
- ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp for simd' after parsing
+ StmtResult
+ ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
+ SourceLocation StartLoc, SourceLocation EndLoc,
+ VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp for simd' after parsing
/// of the associated statement.
- StmtResult ActOnOpenMPForSimdDirective(
- ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp sections' after parsing
+ StmtResult
+ ActOnOpenMPForSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
+ SourceLocation StartLoc, SourceLocation EndLoc,
+ VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp sections' after parsing
/// of the associated statement.
StmtResult ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp section' after parsing of the
+ /// Called on well-formed '\#pragma omp section' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp single' after parsing of the
+ /// Called on well-formed '\#pragma omp single' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp master' after parsing of the
+ /// Called on well-formed '\#pragma omp master' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp critical' after parsing of the
+ /// Called on well-formed '\#pragma omp critical' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName,
ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp parallel for' after parsing
+ /// Called on well-formed '\#pragma omp parallel for' after parsing
/// of the associated statement.
StmtResult ActOnOpenMPParallelForDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp parallel for simd' after
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp parallel for simd' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPParallelForSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp parallel sections' after
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp parallel sections' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt,
SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp task' after parsing of the
+ /// Called on well-formed '\#pragma omp task' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp taskyield'.
+ /// Called on well-formed '\#pragma omp taskyield'.
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp barrier'.
+ /// Called on well-formed '\#pragma omp barrier'.
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp taskwait'.
+ /// Called on well-formed '\#pragma omp taskwait'.
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp taskgroup'.
+ /// Called on well-formed '\#pragma omp taskgroup'.
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp flush'.
+ /// Called on well-formed '\#pragma omp flush'.
StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp ordered' after parsing of the
+ /// Called on well-formed '\#pragma omp ordered' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp atomic' after parsing of the
+ /// Called on well-formed '\#pragma omp atomic' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp target' after parsing of the
+ /// Called on well-formed '\#pragma omp target' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp target data' after parsing of
+ /// Called on well-formed '\#pragma omp target data' after parsing of
/// the associated statement.
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp target enter data' after
+ /// Called on well-formed '\#pragma omp target enter data' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc,
Stmt *AStmt);
- /// \brief Called on well-formed '\#pragma omp target exit data' after
+ /// Called on well-formed '\#pragma omp target exit data' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc,
Stmt *AStmt);
- /// \brief Called on well-formed '\#pragma omp target parallel' after
+ /// Called on well-formed '\#pragma omp target parallel' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt,
SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp target parallel for' after
+ /// Called on well-formed '\#pragma omp target parallel for' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPTargetParallelForDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp teams' after parsing of the
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp teams' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed '\#pragma omp cancellation point'.
+ /// Called on well-formed '\#pragma omp cancellation point'.
StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
SourceLocation EndLoc,
OpenMPDirectiveKind CancelRegion);
- /// \brief Called on well-formed '\#pragma omp cancel'.
+ /// Called on well-formed '\#pragma omp cancel'.
StmtResult ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc,
OpenMPDirectiveKind CancelRegion);
- /// \brief Called on well-formed '\#pragma omp taskloop' after parsing of the
+ /// Called on well-formed '\#pragma omp taskloop' after parsing of the
/// associated statement.
- StmtResult ActOnOpenMPTaskLoopDirective(
- ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp taskloop simd' after parsing of
+ StmtResult
+ ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
+ SourceLocation StartLoc, SourceLocation EndLoc,
+ VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp taskloop simd' after parsing of
/// the associated statement.
StmtResult ActOnOpenMPTaskLoopSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp distribute' after parsing
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp distribute' after parsing
/// of the associated statement.
- StmtResult ActOnOpenMPDistributeDirective(
- ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp target update'.
+ StmtResult
+ ActOnOpenMPDistributeDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
+ SourceLocation StartLoc, SourceLocation EndLoc,
+ VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp target update'.
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc,
Stmt *AStmt);
- /// \brief Called on well-formed '\#pragma omp distribute parallel for' after
+ /// Called on well-formed '\#pragma omp distribute parallel for' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPDistributeParallelForDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp distribute parallel for simd'
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp distribute parallel for simd'
/// after parsing of the associated statement.
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp distribute simd' after
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp distribute simd' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPDistributeSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp target parallel for simd' after
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp target parallel for simd' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPTargetParallelForSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
- /// \brief Called on well-formed '\#pragma omp target simd' after parsing of
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp target simd' after parsing of
/// the associated statement.
- StmtResult ActOnOpenMPTargetSimdDirective(
- ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ StmtResult
+ ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
+ SourceLocation StartLoc, SourceLocation EndLoc,
+ VarsWithInheritedDSAType &VarsWithImplicitDSA);
/// Called on well-formed '\#pragma omp teams distribute' after parsing of
/// the associated statement.
StmtResult ActOnOpenMPTeamsDistributeDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
/// Called on well-formed '\#pragma omp teams distribute simd' after parsing
/// of the associated statement.
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
/// Called on well-formed '\#pragma omp teams distribute parallel for simd'
/// after parsing of the associated statement.
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
/// Called on well-formed '\#pragma omp teams distribute parallel for'
/// after parsing of the associated statement.
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
/// Called on well-formed '\#pragma omp target teams' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
@@ -8921,36 +9001,32 @@ public:
/// of the associated statement.
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
/// Called on well-formed '\#pragma omp target teams distribute parallel for'
/// after parsing of the associated statement.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
/// Called on well-formed '\#pragma omp target teams distribute parallel for
/// simd' after parsing of the associated statement.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
/// Called on well-formed '\#pragma omp target teams distribute simd' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc,
- llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA);
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
/// Checks correctness of linear modifiers.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
SourceLocation LinLoc);
/// Checks that the specified declaration matches requirements for the linear
/// decls.
- bool CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc,
+ bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
OpenMPLinearClauseKind LinKind, QualType Type);
- /// \brief Called on well-formed '\#pragma omp declare simd' after parsing of
+ /// Called on well-formed '\#pragma omp declare simd' after parsing of
/// the associated method/function.
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(
DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS,
@@ -8963,50 +9039,50 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'if' clause.
+ /// Called on well-formed 'if' clause.
OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
Expr *Condition, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation NameModifierLoc,
SourceLocation ColonLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'final' clause.
+ /// Called on well-formed 'final' clause.
OMPClause *ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'num_threads' clause.
+ /// Called on well-formed 'num_threads' clause.
OMPClause *ActOnOpenMPNumThreadsClause(Expr *NumThreads,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'safelen' clause.
+ /// Called on well-formed 'safelen' clause.
OMPClause *ActOnOpenMPSafelenClause(Expr *Length,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'simdlen' clause.
+ /// Called on well-formed 'simdlen' clause.
OMPClause *ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'collapse' clause.
+ /// Called on well-formed 'collapse' clause.
OMPClause *ActOnOpenMPCollapseClause(Expr *NumForLoops,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'ordered' clause.
+ /// Called on well-formed 'ordered' clause.
OMPClause *
ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc,
SourceLocation LParenLoc = SourceLocation(),
Expr *NumForLoops = nullptr);
- /// \brief Called on well-formed 'grainsize' clause.
+ /// Called on well-formed 'grainsize' clause.
OMPClause *ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'num_tasks' clause.
+ /// Called on well-formed 'num_tasks' clause.
OMPClause *ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'hint' clause.
+ /// Called on well-formed 'hint' clause.
OMPClause *ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
@@ -9017,13 +9093,13 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'default' clause.
+ /// Called on well-formed 'default' clause.
OMPClause *ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
SourceLocation KindLoc,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'proc_bind' clause.
+ /// Called on well-formed 'proc_bind' clause.
OMPClause *ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
SourceLocation KindLoc,
SourceLocation StartLoc,
@@ -9035,7 +9111,7 @@ public:
SourceLocation StartLoc, SourceLocation LParenLoc,
ArrayRef<SourceLocation> ArgumentsLoc, SourceLocation DelimLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'schedule' clause.
+ /// Called on well-formed 'schedule' clause.
OMPClause *ActOnOpenMPScheduleClause(
OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
@@ -9044,37 +9120,37 @@ public:
OMPClause *ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'nowait' clause.
+ /// Called on well-formed 'nowait' clause.
OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'untied' clause.
+ /// Called on well-formed 'untied' clause.
OMPClause *ActOnOpenMPUntiedClause(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'mergeable' clause.
+ /// Called on well-formed 'mergeable' clause.
OMPClause *ActOnOpenMPMergeableClause(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'read' clause.
+ /// Called on well-formed 'read' clause.
OMPClause *ActOnOpenMPReadClause(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'write' clause.
+ /// Called on well-formed 'write' clause.
OMPClause *ActOnOpenMPWriteClause(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'update' clause.
+ /// Called on well-formed 'update' clause.
OMPClause *ActOnOpenMPUpdateClause(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'capture' clause.
+ /// Called on well-formed 'capture' clause.
OMPClause *ActOnOpenMPCaptureClause(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'seq_cst' clause.
+ /// Called on well-formed 'seq_cst' clause.
OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'threads' clause.
+ /// Called on well-formed 'threads' clause.
OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'simd' clause.
+ /// Called on well-formed 'simd' clause.
OMPClause *ActOnOpenMPSIMDClause(SourceLocation StartLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'nogroup' clause.
+ /// Called on well-formed 'nogroup' clause.
OMPClause *ActOnOpenMPNogroupClause(SourceLocation StartLoc,
SourceLocation EndLoc);
@@ -9087,27 +9163,27 @@ public:
OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
SourceLocation DepLinMapLoc);
- /// \brief Called on well-formed 'private' clause.
+ /// Called on well-formed 'private' clause.
OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'firstprivate' clause.
+ /// Called on well-formed 'firstprivate' clause.
OMPClause *ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'lastprivate' clause.
+ /// Called on well-formed 'lastprivate' clause.
OMPClause *ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'shared' clause.
+ /// Called on well-formed 'shared' clause.
OMPClause *ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'reduction' clause.
+ /// Called on well-formed 'reduction' clause.
OMPClause *ActOnOpenMPReductionClause(
ArrayRef<Expr *> VarList, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
@@ -9128,80 +9204,80 @@ public:
CXXScopeSpec &ReductionIdScopeSpec,
const DeclarationNameInfo &ReductionId,
ArrayRef<Expr *> UnresolvedReductions = llvm::None);
- /// \brief Called on well-formed 'linear' clause.
+ /// Called on well-formed 'linear' clause.
OMPClause *
ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
SourceLocation StartLoc, SourceLocation LParenLoc,
OpenMPLinearClauseKind LinKind, SourceLocation LinLoc,
SourceLocation ColonLoc, SourceLocation EndLoc);
- /// \brief Called on well-formed 'aligned' clause.
+ /// Called on well-formed 'aligned' clause.
OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList,
Expr *Alignment,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation ColonLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'copyin' clause.
+ /// Called on well-formed 'copyin' clause.
OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'copyprivate' clause.
+ /// Called on well-formed 'copyprivate' clause.
OMPClause *ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'flush' pseudo clause.
+ /// Called on well-formed 'flush' pseudo clause.
OMPClause *ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'depend' clause.
+ /// Called on well-formed 'depend' clause.
OMPClause *
ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc,
SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'device' clause.
+ /// Called on well-formed 'device' clause.
OMPClause *ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'map' clause.
+ /// Called on well-formed 'map' clause.
OMPClause *
ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
SourceLocation MapLoc, SourceLocation ColonLoc,
ArrayRef<Expr *> VarList, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc);
- /// \brief Called on well-formed 'num_teams' clause.
+ /// Called on well-formed 'num_teams' clause.
OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'thread_limit' clause.
+ /// Called on well-formed 'thread_limit' clause.
OMPClause *ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'priority' clause.
+ /// Called on well-formed 'priority' clause.
OMPClause *ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'dist_schedule' clause.
+ /// Called on well-formed 'dist_schedule' clause.
OMPClause *ActOnOpenMPDistScheduleClause(
OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize,
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc,
SourceLocation CommaLoc, SourceLocation EndLoc);
- /// \brief Called on well-formed 'defaultmap' clause.
+ /// Called on well-formed 'defaultmap' clause.
OMPClause *ActOnOpenMPDefaultmapClause(
OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
SourceLocation KindLoc, SourceLocation EndLoc);
- /// \brief Called on well-formed 'to' clause.
+ /// Called on well-formed 'to' clause.
OMPClause *ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief Called on well-formed 'from' clause.
+ /// Called on well-formed 'from' clause.
OMPClause *ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -9217,18 +9293,25 @@ public:
SourceLocation LParenLoc,
SourceLocation EndLoc);
- /// \brief The kind of conversion being performed.
+ /// The kind of conversion being performed.
enum CheckedConversionKind {
- /// \brief An implicit conversion.
+ /// An implicit conversion.
CCK_ImplicitConversion,
- /// \brief A C-style cast.
+ /// A C-style cast.
CCK_CStyleCast,
- /// \brief A functional-style cast.
+ /// A functional-style cast.
CCK_FunctionalCast,
- /// \brief A cast other than a C-style cast.
- CCK_OtherCast
+ /// A cast other than a C-style cast.
+ CCK_OtherCast,
+ /// A conversion for an operand of a builtin overloaded operator.
+ CCK_ForBuiltinOverloadedOp
};
+ static bool isCast(CheckedConversionKind CCK) {
+ return CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast ||
+ CCK == CCK_OtherCast;
+ }
+
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
/// cast. If there is already an implicit cast, merge into the existing one.
/// If isLvalue, the result of the cast is an lvalue.
@@ -9462,7 +9545,7 @@ public:
QualType LHSType, ExprResult &RHS, bool Diagnose = true,
bool DiagnoseCFAudited = false, bool ConvertRHS = true);
- // \brief If the lhs type is a transparent union, check whether we
+ // If the lhs type is a transparent union, check whether we
// can initialize the transparent union with the given expression.
AssignConvertType CheckTransparentUnionArgumentConstraints(QualType ArgType,
ExprResult &RHS);
@@ -9515,8 +9598,8 @@ public:
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
BinaryOperatorKind Opc, bool IsCompAssign = false);
QualType CheckCompareOperands( // C99 6.5.8/9
- ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
- BinaryOperatorKind Opc, bool isRelational);
+ ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
+ BinaryOperatorKind Opc);
QualType CheckBitwiseOperands( // C99 6.5.[10...12]
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
BinaryOperatorKind Opc);
@@ -9572,7 +9655,8 @@ public:
bool AllowBothBool, bool AllowBoolConversion);
QualType GetSignedVectorType(QualType V);
QualType CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS,
- SourceLocation Loc, bool isRelational);
+ SourceLocation Loc,
+ BinaryOperatorKind Opc);
QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc);
@@ -9609,11 +9693,11 @@ public:
Expr *CastExpr, CastKind &CastKind,
ExprValueKind &VK, CXXCastPath &Path);
- /// \brief Force an expression with unknown-type to an expression of the
+ /// Force an expression with unknown-type to an expression of the
/// given type.
ExprResult forceUnknownAnyToType(Expr *E, QualType ToType);
- /// \brief Type-check an expression that's being passed to an
+ /// Type-check an expression that's being passed to an
/// __unknown_anytype parameter.
ExprResult checkUnknownAnyArg(SourceLocation callLoc,
Expr *result, QualType &paramType);
@@ -9625,7 +9709,7 @@ public:
bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
CastKind &Kind);
- /// \brief Prepare `SplattedExpr` for a vector splat operation, adding
+ /// Prepare `SplattedExpr` for a vector splat operation, adding
/// implicit casts if necessary.
ExprResult prepareVectorSplat(QualType VectorTy, Expr *SplattedExpr);
@@ -9644,7 +9728,7 @@ public:
enum ARCConversionResult { ACR_okay, ACR_unbridged, ACR_error };
- /// \brief Checks for invalid conversions and casts between
+ /// Checks for invalid conversions and casts between
/// retainable pointers and other pointer kinds for ARC and Weak.
ARCConversionResult CheckObjCConversion(SourceRange castRange,
QualType castType, Expr *&op,
@@ -9687,18 +9771,18 @@ public:
SourceRange RecRange,
QualType &ReturnType, ExprValueKind &VK);
- /// \brief Determine the result of a message send expression based on
+ /// Determine the result of a message send expression based on
/// the type of the receiver, the method expected to receive the message,
/// and the form of the message send.
QualType getMessageSendResultType(QualType ReceiverType,
ObjCMethodDecl *Method,
bool isClassMessage, bool isSuperMessage);
- /// \brief If the given expression involves a message send to a method
+ /// If the given expression involves a message send to a method
/// with a related result type, emit a note describing what happened.
void EmitRelatedResultTypeNote(const Expr *E);
- /// \brief Given that we had incompatible pointer types in a return
+ /// Given that we had incompatible pointer types in a return
/// statement, check whether we're in a method with a related result
/// type, and if so, emit a note describing what happened.
void EmitRelatedResultTypeNoteForReturn(QualType destType);
@@ -9772,7 +9856,7 @@ public:
/// being used as a boolean condition, warn if it's an assignment.
void DiagnoseAssignmentAsCondition(Expr *E);
- /// \brief Redundant parentheses over an equality comparison can indicate
+ /// Redundant parentheses over an equality comparison can indicate
/// that the user intended an assignment used as condition.
void DiagnoseEqualityWithExtraParens(ParenExpr *ParenE);
@@ -9791,7 +9875,7 @@ public:
/// in the global scope.
bool CheckObjCDeclScope(Decl *D);
- /// \brief Abstract base class used for diagnosing integer constant
+ /// Abstract base class used for diagnosing integer constant
/// expression violations.
class VerifyICEDiagnoser {
public:
@@ -9987,7 +10071,7 @@ public:
/// will get it wrong. Returns CFT_Host if D is null.
CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D,
bool IgnoreImplicitHDAttr = false);
- CUDAFunctionTarget IdentifyCUDATarget(const AttributeList *Attr);
+ CUDAFunctionTarget IdentifyCUDATarget(const ParsedAttributesView &Attrs);
/// Gets the CUDA target for the current context.
CUDAFunctionTarget CurrentCUDATarget() {
@@ -10086,6 +10170,16 @@ public:
bool isEmptyCudaConstructor(SourceLocation Loc, CXXConstructorDecl *CD);
bool isEmptyCudaDestructor(SourceLocation Loc, CXXDestructorDecl *CD);
+ // \brief Checks that initializers of \p Var satisfy CUDA restrictions. In
+ // case of error emits appropriate diagnostic and invalidates \p Var.
+ //
+ // \details CUDA allows only empty constructors as initializers for global
+ // variables (see E.2.3.1, CUDA 7.5). The same restriction also applies to all
+ // __shared__ variables whether they are local or not (they all are implicitly
+ // static in CUDA). One exception is that CUDA allows constant initializers
+ // for __constant__ and __device__ variables.
+ void checkAllowedCUDAInitializer(VarDecl *VD);
+
/// Check whether NewFD is a valid overload for CUDA. Emits
/// diagnostics and invalidates NewFD if not.
void checkCUDATargetOverload(FunctionDecl *NewFD,
@@ -10095,48 +10189,48 @@ public:
/// \name Code completion
//@{
- /// \brief Describes the context in which code completion occurs.
+ /// Describes the context in which code completion occurs.
enum ParserCompletionContext {
- /// \brief Code completion occurs at top-level or namespace context.
+ /// Code completion occurs at top-level or namespace context.
PCC_Namespace,
- /// \brief Code completion occurs within a class, struct, or union.
+ /// Code completion occurs within a class, struct, or union.
PCC_Class,
- /// \brief Code completion occurs within an Objective-C interface, protocol,
+ /// Code completion occurs within an Objective-C interface, protocol,
/// or category.
PCC_ObjCInterface,
- /// \brief Code completion occurs within an Objective-C implementation or
+ /// Code completion occurs within an Objective-C implementation or
/// category implementation
PCC_ObjCImplementation,
- /// \brief Code completion occurs within the list of instance variables
+ /// Code completion occurs within the list of instance variables
/// in an Objective-C interface, protocol, category, or implementation.
PCC_ObjCInstanceVariableList,
- /// \brief Code completion occurs following one or more template
+ /// Code completion occurs following one or more template
/// headers.
PCC_Template,
- /// \brief Code completion occurs following one or more template
+ /// Code completion occurs following one or more template
/// headers within a class.
PCC_MemberTemplate,
- /// \brief Code completion occurs within an expression.
+ /// Code completion occurs within an expression.
PCC_Expression,
- /// \brief Code completion occurs within a statement, which may
+ /// Code completion occurs within a statement, which may
/// also be an expression or a declaration.
PCC_Statement,
- /// \brief Code completion occurs at the beginning of the
+ /// Code completion occurs at the beginning of the
/// initialization statement (or expression) in a for loop.
PCC_ForInit,
- /// \brief Code completion occurs within the condition of an if,
+ /// Code completion occurs within the condition of an if,
/// while, switch, or for statement.
PCC_Condition,
- /// \brief Code completion occurs within the body of a function on a
+ /// Code completion occurs within the body of a function on a
/// recovery path, where we do not have a specific handle on our position
/// in the grammar.
PCC_RecoveryInFunction,
- /// \brief Code completion occurs where only a type is permitted.
+ /// Code completion occurs where only a type is permitted.
PCC_Type,
- /// \brief Code completion occurs in a parenthesized expression, which
+ /// Code completion occurs in a parenthesized expression, which
/// might also be a type cast.
PCC_ParenthesizedExpression,
- /// \brief Code completion occurs within a sequence of declaration
+ /// Code completion occurs within a sequence of declaration
/// specifiers within a function, method, or block.
PCC_LocalDeclarationSpecifiers
};
@@ -10151,7 +10245,7 @@ public:
struct CodeCompleteExpressionData;
void CodeCompleteExpression(Scope *S,
const CodeCompleteExpressionData &Data);
- void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
+ void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, Expr *OtherOpBase,
SourceLocation OpLoc, bool IsArrow,
bool IsBaseExprStatement);
void CodeCompletePostfixExpression(Scope *S, ExprResult LHS);
@@ -10301,6 +10395,9 @@ private:
bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+ bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+ bool CheckHexagonBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall);
+ bool CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall);
bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall);
@@ -10333,10 +10430,12 @@ private:
ExprResult SemaBuiltinNontemporalOverloaded(ExprResult TheCallResult);
ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,
AtomicExpr::AtomicOp Op);
+ ExprResult SemaBuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult,
+ bool IsDelete);
bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
llvm::APSInt &Result);
- bool SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum,
- int Low, int High);
+ bool SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low,
+ int High, bool RangeIsError = true);
bool SemaBuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum,
unsigned Multiple);
bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall,
@@ -10396,13 +10495,16 @@ private:
const AttrVec *Attrs = nullptr,
const FunctionDecl *FD = nullptr);
- void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
+public:
+ void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS);
+
+private:
void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
void CheckBoolLikeConversion(Expr *E, SourceLocation CC);
void CheckForIntOverflow(Expr *E);
void CheckUnsequencedOperations(Expr *E);
- /// \brief Perform semantic checks on a completed expression. This will either
+ /// Perform semantic checks on a completed expression. This will either
/// be a full-expression or a default argument expression.
void CheckCompletedExpr(Expr *E, SourceLocation CheckLoc = SourceLocation(),
bool IsConstexpr = false);
@@ -10415,11 +10517,11 @@ private:
DeclarationName FieldName,
const CXXRecordDecl *RD);
- /// \brief Check if the given expression contains 'break' or 'continue'
+ /// Check if the given expression contains 'break' or 'continue'
/// statement that produces control flow different from GCC.
void CheckBreakContinueBinding(Expr *E);
- /// \brief Check whether receiver is mutable ObjC container which
+ /// Check whether receiver is mutable ObjC container which
/// attempts to add itself into the container
void CheckObjCCircularContainer(ObjCMessageExpr *Message);
@@ -10427,7 +10529,7 @@ private:
void AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc,
bool DeleteWasArrayForm);
public:
- /// \brief Register a magic integral constant to be used as a type tag.
+ /// Register a magic integral constant to be used as a type tag.
void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind,
uint64_t MagicValue, QualType Type,
bool LayoutCompatible, bool MustBeNull);
@@ -10453,21 +10555,21 @@ public:
typedef std::pair<const IdentifierInfo *, uint64_t> TypeTagMagicValue;
private:
- /// \brief A map from magic value to type information.
+ /// A map from magic value to type information.
std::unique_ptr<llvm::DenseMap<TypeTagMagicValue, TypeTagData>>
TypeTagForDatatypeMagicValues;
- /// \brief Peform checks on a call of a function with argument_with_type_tag
+ /// Peform checks on a call of a function with argument_with_type_tag
/// or pointer_with_type_tag attributes.
void CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr,
const ArrayRef<const Expr *> ExprArgs,
SourceLocation CallSiteLoc);
- /// \brief Check if we are taking the address of a packed field
+ /// Check if we are taking the address of a packed field
/// as this may be a problem if the pointer value is dereferenced.
void CheckAddressOfPackedMember(Expr *rhs);
- /// \brief The parser's current scope.
+ /// The parser's current scope.
///
/// The parser maintains this state here.
Scope *CurScope;
@@ -10482,7 +10584,7 @@ private:
IdentifierInfo *Ident_NSError = nullptr;
- /// \brief The handler for the FileChanged preprocessor events.
+ /// The handler for the FileChanged preprocessor events.
///
/// Used for diagnostics that implement custom semantic analysis for #include
/// directives, like -Wpragma-pack.
@@ -10505,7 +10607,7 @@ public:
/// Retrieve the identifier "NSError".
IdentifierInfo *getNSErrorIdent();
- /// \brief Retrieve the parser's current scope.
+ /// Retrieve the parser's current scope.
///
/// This routine must only be used when it is certain that semantic analysis
/// and the parser are in precisely the same context, which is not the case
@@ -10536,7 +10638,7 @@ public:
return DC;
}
- /// \brief To be used for checking whether the arguments being passed to
+ /// To be used for checking whether the arguments being passed to
/// function exceeds the number of parameters expected for it.
static bool TooManyArguments(size_t NumParams, size_t NumArgs,
bool PartialOverloading = false) {
@@ -10581,7 +10683,7 @@ private:
}
};
- /// \brief Helper class that collects misaligned member designations and
+ /// Helper class that collects misaligned member designations and
/// their location info for delayed diagnostics.
struct MisalignedMember {
Expr *E;
@@ -10598,28 +10700,28 @@ private:
bool operator==(const MisalignedMember &m) { return this->E == m.E; }
};
- /// \brief Small set of gathered accesses to potentially misaligned members
+ /// Small set of gathered accesses to potentially misaligned members
/// due to the packed attribute.
SmallVector<MisalignedMember, 4> MisalignedMembers;
- /// \brief Adds an expression to the set of gathered misaligned members.
+ /// Adds an expression to the set of gathered misaligned members.
void AddPotentialMisalignedMembers(Expr *E, RecordDecl *RD, ValueDecl *MD,
CharUnits Alignment);
public:
- /// \brief Diagnoses the current set of gathered accesses. This typically
+ /// Diagnoses the current set of gathered accesses. This typically
/// happens at full expression level. The set is cleared after emitting the
/// diagnostics.
void DiagnoseMisalignedMembers();
- /// \brief This function checks if the expression is in the sef of potentially
+ /// This function checks if the expression is in the sef of potentially
/// misaligned members and it is converted to some pointer type T with lower
/// or equal alignment requirements. If so it removes it. This is used when
/// we do not want to diagnose such misaligned access (e.g. in conversions to
/// void*).
void DiscardMisalignedMemberAddress(const Type *T, Expr *E);
- /// \brief This function calls Action when it determines that E designates a
+ /// This function calls Action when it determines that E designates a
/// misaligned member due to the packed attribute. This is used to emit
/// local diagnostics like in reference binding.
void RefersToMemberWithReducedAlignment(
@@ -10628,31 +10730,31 @@ public:
Action);
};
-/// \brief RAII object that enters a new expression evaluation context.
+/// RAII object that enters a new expression evaluation context.
class EnterExpressionEvaluationContext {
Sema &Actions;
bool Entered = true;
public:
-
- EnterExpressionEvaluationContext(Sema &Actions,
- Sema::ExpressionEvaluationContext NewContext,
- Decl *LambdaContextDecl = nullptr,
- bool IsDecltype = false,
- bool ShouldEnter = true)
+ EnterExpressionEvaluationContext(
+ Sema &Actions, Sema::ExpressionEvaluationContext NewContext,
+ Decl *LambdaContextDecl = nullptr,
+ Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext =
+ Sema::ExpressionEvaluationContextRecord::EK_Other,
+ bool ShouldEnter = true)
: Actions(Actions), Entered(ShouldEnter) {
if (Entered)
Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl,
- IsDecltype);
+ ExprContext);
}
- EnterExpressionEvaluationContext(Sema &Actions,
- Sema::ExpressionEvaluationContext NewContext,
- Sema::ReuseLambdaContextDecl_t,
- bool IsDecltype = false)
- : Actions(Actions) {
- Actions.PushExpressionEvaluationContext(NewContext,
- Sema::ReuseLambdaContextDecl,
- IsDecltype);
+ EnterExpressionEvaluationContext(
+ Sema &Actions, Sema::ExpressionEvaluationContext NewContext,
+ Sema::ReuseLambdaContextDecl_t,
+ Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext =
+ Sema::ExpressionEvaluationContextRecord::EK_Other)
+ : Actions(Actions) {
+ Actions.PushExpressionEvaluationContext(
+ NewContext, Sema::ReuseLambdaContextDecl, ExprContext);
}
enum InitListTag { InitList };
@@ -10666,7 +10768,7 @@ public:
if (ShouldEnter && Actions.isUnevaluatedContext() &&
Actions.getLangOpts().CPlusPlus11) {
Actions.PushExpressionEvaluationContext(
- Sema::ExpressionEvaluationContext::UnevaluatedList, nullptr, false);
+ Sema::ExpressionEvaluationContext::UnevaluatedList);
Entered = true;
}
}
@@ -10681,11 +10783,11 @@ DeductionFailureInfo
MakeDeductionFailureInfo(ASTContext &Context, Sema::TemplateDeductionResult TDK,
sema::TemplateDeductionInfo &Info);
-/// \brief Contains a late templated function.
+/// Contains a late templated function.
/// Will be parsed at the end of the translation unit, used by Sema & Parser.
struct LateParsedTemplate {
CachedTokens Toks;
- /// \brief The template function declaration to be late parsed.
+ /// The template function declaration to be late parsed.
Decl *D;
};
diff --git a/include/clang/Sema/SemaConsumer.h b/include/clang/Sema/SemaConsumer.h
index 676646afbd595..a2caf86c36533 100644
--- a/include/clang/Sema/SemaConsumer.h
+++ b/include/clang/Sema/SemaConsumer.h
@@ -20,7 +20,7 @@
namespace clang {
class Sema;
- /// \brief An abstract interface that should be implemented by
+ /// An abstract interface that should be implemented by
/// clients that read ASTs and then require further semantic
/// analysis of the entities in those ASTs.
class SemaConsumer : public ASTConsumer {
@@ -30,12 +30,12 @@ namespace clang {
ASTConsumer::SemaConsumer = true;
}
- /// \brief Initialize the semantic consumer with the Sema instance
+ /// Initialize the semantic consumer with the Sema instance
/// being used to perform semantic analysis on the abstract syntax
/// tree.
virtual void InitializeSema(Sema &S) {}
- /// \brief Inform the semantic consumer that Sema is no longer available.
+ /// Inform the semantic consumer that Sema is no longer available.
virtual void ForgetSema() {}
// isa/cast/dyn_cast support
diff --git a/include/clang/Sema/SemaFixItUtils.h b/include/clang/Sema/SemaFixItUtils.h
index 343ccfb3d6307..84dc58754b7be 100644
--- a/include/clang/Sema/SemaFixItUtils.h
+++ b/include/clang/Sema/SemaFixItUtils.h
@@ -1,4 +1,4 @@
-//===--- SemaFixItUtils.h - Sema FixIts -----------------------------------===//
+//===--- SemaFixItUtils.h - Sema FixIts -------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
index 4dc215ba21cb7..86ab703a5b3af 100644
--- a/include/clang/Sema/SemaInternal.h
+++ b/include/clang/Sema/SemaInternal.h
@@ -101,6 +101,27 @@ inline InheritableAttr *getDLLAttr(Decl *D) {
return nullptr;
}
+/// Retrieve the depth and index of a template parameter.
+inline std::pair<unsigned, unsigned> getDepthAndIndex(NamedDecl *ND) {
+ if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
+ return std::make_pair(TTP->getDepth(), TTP->getIndex());
+
+ if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(ND))
+ return std::make_pair(NTTP->getDepth(), NTTP->getIndex());
+
+ const auto *TTP = cast<TemplateTemplateParmDecl>(ND);
+ return std::make_pair(TTP->getDepth(), TTP->getIndex());
+}
+
+/// Retrieve the depth and index of an unexpanded parameter pack.
+inline std::pair<unsigned, unsigned>
+getDepthAndIndex(UnexpandedParameterPack UPP) {
+ if (const auto *TTP = UPP.first.dyn_cast<const TemplateTypeParmType *>())
+ return std::make_pair(TTP->getDepth(), TTP->getIndex());
+
+ return getDepthAndIndex(UPP.first.get<NamedDecl *>());
+}
+
class TypoCorrectionConsumer : public VisibleDeclConsumer {
typedef SmallVector<TypoCorrection, 1> TypoResultList;
typedef llvm::StringMap<TypoResultList> TypoResultsMap;
@@ -139,13 +160,13 @@ public:
return CorrectionResults.empty() && ValidatedCorrections.size() == 1;
}
- /// \brief Return the list of TypoCorrections for the given identifier from
+ /// Return the list of TypoCorrections for the given identifier from
/// the set of corrections that have the closest edit distance, if any.
TypoResultList &operator[](StringRef Name) {
return CorrectionResults.begin()->second[Name];
}
- /// \brief Return the edit distance of the corrections that have the
+ /// Return the edit distance of the corrections that have the
/// closest/best edit distance from the original typop.
unsigned getBestEditDistance(bool Normalized) {
if (CorrectionResults.empty())
@@ -155,28 +176,28 @@ public:
return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED;
}
- /// \brief Set-up method to add to the consumer the set of namespaces to use
+ /// Set-up method to add to the consumer the set of namespaces to use
/// in performing corrections to nested name specifiers. This method also
/// implicitly adds all of the known classes in the current AST context to the
/// to the consumer for correcting nested name specifiers.
void
addNamespaces(const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces);
- /// \brief Return the next typo correction that passes all internal filters
+ /// Return the next typo correction that passes all internal filters
/// and is deemed valid by the consumer's CorrectionCandidateCallback,
/// starting with the corrections that have the closest edit distance. An
/// empty TypoCorrection is returned once no more viable corrections remain
/// in the consumer.
const TypoCorrection &getNextCorrection();
- /// \brief Get the last correction returned by getNextCorrection().
+ /// Get the last correction returned by getNextCorrection().
const TypoCorrection &getCurrentCorrection() {
return CurrentTCIndex < ValidatedCorrections.size()
? ValidatedCorrections[CurrentTCIndex]
: ValidatedCorrections[0]; // The empty correction.
}
- /// \brief Return the next typo correction like getNextCorrection, but keep
+ /// Return the next typo correction like getNextCorrection, but keep
/// the internal state pointed to the current correction (i.e. the next time
/// getNextCorrection is called, it will return the same correction returned
/// by peekNextcorrection).
@@ -187,27 +208,27 @@ public:
return TC;
}
- /// \brief Reset the consumer's position in the stream of viable corrections
+ /// Reset the consumer's position in the stream of viable corrections
/// (i.e. getNextCorrection() will return each of the previously returned
/// corrections in order before returning any new corrections).
void resetCorrectionStream() {
CurrentTCIndex = 0;
}
- /// \brief Return whether the end of the stream of corrections has been
+ /// Return whether the end of the stream of corrections has been
/// reached.
bool finished() {
return CorrectionResults.empty() &&
CurrentTCIndex >= ValidatedCorrections.size();
}
- /// \brief Save the current position in the correction stream (overwriting any
+ /// Save the current position in the correction stream (overwriting any
/// previously saved position).
void saveCurrentPosition() {
SavedTCIndex = CurrentTCIndex;
}
- /// \brief Restore the saved position in the correction stream.
+ /// Restore the saved position in the correction stream.
void restoreSavedPosition() {
CurrentTCIndex = SavedTCIndex;
}
@@ -241,7 +262,7 @@ private:
std::map<unsigned, SpecifierInfoList> DistanceMap;
- /// \brief Helper for building the list of DeclContexts between the current
+ /// Helper for building the list of DeclContexts between the current
/// context and the top of the translation unit
static DeclContextList buildContextChain(DeclContext *Start);
@@ -252,11 +273,11 @@ private:
NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
CXXScopeSpec *CurScopeSpec);
- /// \brief Add the DeclContext (a namespace or record) to the set, computing
+ /// Add the DeclContext (a namespace or record) to the set, computing
/// the corresponding NestedNameSpecifier and its distance in the process.
void addNameSpecifier(DeclContext *Ctx);
- /// \brief Provides flat iteration over specifiers, sorted by distance.
+ /// Provides flat iteration over specifiers, sorted by distance.
class iterator
: public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
SpecifierInfo> {
@@ -295,21 +316,21 @@ private:
void addName(StringRef Name, NamedDecl *ND,
NestedNameSpecifier *NNS = nullptr, bool isKeyword = false);
- /// \brief Find any visible decls for the given typo correction candidate.
+ /// Find any visible decls for the given typo correction candidate.
/// If none are found, it to the set of candidates for which qualified lookups
/// will be performed to find possible nested name specifier changes.
bool resolveCorrection(TypoCorrection &Candidate);
- /// \brief Perform qualified lookups on the queued set of typo correction
+ /// Perform qualified lookups on the queued set of typo correction
/// candidates and add the nested name specifier changes to each candidate if
/// a lookup succeeds (at which point the candidate will be returned to the
/// main pool of potential corrections).
void performQualifiedLookups();
- /// \brief The name written that is a typo in the source.
+ /// The name written that is a typo in the source.
IdentifierInfo *Typo;
- /// \brief The results found that have the smallest edit distance
+ /// The results found that have the smallest edit distance
/// found (so far) with the typo name.
///
/// The pointer value being set to the current DeclContext indicates
diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h
index df40b134f0a7d..dfdc4ebc3643d 100644
--- a/include/clang/Sema/SemaLambda.h
+++ b/include/clang/Sema/SemaLambda.h
@@ -8,19 +8,23 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief This file provides some common utility functions for processing
+/// This file provides some common utility functions for processing
/// Lambdas.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SEMA_SEMALAMBDA_H
#define LLVM_CLANG_SEMA_SEMALAMBDA_H
+
#include "clang/AST/ASTLambda.h"
-#include "clang/Sema/ScopeInfo.h"
+
namespace clang {
+namespace sema {
+class FunctionScopeInfo;
+}
class Sema;
-/// \brief Examines the FunctionScopeInfo stack to determine the nearest
+/// Examines the FunctionScopeInfo stack to determine the nearest
/// enclosing lambda (to the current lambda) that is 'capture-capable' for
/// the variable referenced in the current lambda (i.e. \p VarToCapture).
/// If successful, returns the index into Sema's FunctionScopeInfo stack
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
index 644d55b93f1b1..c0dee3e82d58a 100644
--- a/include/clang/Sema/Template.h
+++ b/include/clang/Sema/Template.h
@@ -1,26 +1,49 @@
-//===------- SemaTemplate.h - C++ Templates ---------------------*- C++ -*-===/
+//===- SemaTemplate.h - C++ Templates ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//===----------------------------------------------------------------------===/
+//===----------------------------------------------------------------------===//
//
-// This file provides types used in the semantic analysis of C++ templates.
+// This file provides types used in the semantic analysis of C++ templates.
//
-//===----------------------------------------------------------------------===/
+//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_SEMA_TEMPLATE_H
#define LLVM_CLANG_SEMA_TEMPLATE_H
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Sema/Sema.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <utility>
namespace clang {
- /// \brief Data structure that captures multiple levels of template argument
+
+class ASTContext;
+class BindingDecl;
+class CXXMethodDecl;
+class Decl;
+class DeclaratorDecl;
+class DeclContext;
+class EnumDecl;
+class FunctionDecl;
+class NamedDecl;
+class ParmVarDecl;
+class TagDecl;
+class TypedefNameDecl;
+class TypeSourceInfo;
+class VarDecl;
+
+ /// Data structure that captures multiple levels of template argument
/// lists for use in template instantiation.
///
/// Multiple levels of template arguments occur when instantiating the
@@ -40,47 +63,47 @@ namespace clang {
/// list will contain a template argument list (int) at depth 0 and a
/// template argument list (17) at depth 1.
class MultiLevelTemplateArgumentList {
- /// \brief The template argument list at a certain template depth
- typedef ArrayRef<TemplateArgument> ArgList;
+ /// The template argument list at a certain template depth
+ using ArgList = ArrayRef<TemplateArgument>;
- /// \brief The template argument lists, stored from the innermost template
+ /// The template argument lists, stored from the innermost template
/// argument list (first) to the outermost template argument list (last).
SmallVector<ArgList, 4> TemplateArgumentLists;
- /// \brief The number of outer levels of template arguments that are not
+ /// The number of outer levels of template arguments that are not
/// being substituted.
unsigned NumRetainedOuterLevels = 0;
public:
- /// \brief Construct an empty set of template argument lists.
- MultiLevelTemplateArgumentList() { }
+ /// Construct an empty set of template argument lists.
+ MultiLevelTemplateArgumentList() = default;
- /// \brief Construct a single-level template argument list.
+ /// Construct a single-level template argument list.
explicit
MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
addOuterTemplateArguments(&TemplateArgs);
}
- /// \brief Determine the number of levels in this template argument
+ /// Determine the number of levels in this template argument
/// list.
unsigned getNumLevels() const {
return TemplateArgumentLists.size() + NumRetainedOuterLevels;
}
- /// \brief Determine the number of substituted levels in this template
+ /// Determine the number of substituted levels in this template
/// argument list.
unsigned getNumSubstitutedLevels() const {
return TemplateArgumentLists.size();
}
- /// \brief Retrieve the template argument at a given depth and index.
+ /// Retrieve the template argument at a given depth and index.
const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
return TemplateArgumentLists[getNumLevels() - Depth - 1][Index];
}
- /// \brief Determine whether there is a non-NULL template argument at the
+ /// Determine whether there is a non-NULL template argument at the
/// given depth and index.
///
/// There must exist a template argument list at the given depth.
@@ -96,7 +119,7 @@ namespace clang {
return !(*this)(Depth, Index).isNull();
}
- /// \brief Clear out a specific template argument.
+ /// Clear out a specific template argument.
void setArgument(unsigned Depth, unsigned Index,
TemplateArgument Arg) {
assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
@@ -106,14 +129,14 @@ namespace clang {
= Arg;
}
- /// \brief Add a new outermost level to the multi-level template argument
+ /// Add a new outermost level to the multi-level template argument
/// list.
void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
addOuterTemplateArguments(ArgList(TemplateArgs->data(),
TemplateArgs->size()));
}
- /// \brief Add a new outmost level to the multi-level template argument
+ /// Add a new outmost level to the multi-level template argument
/// list.
void addOuterTemplateArguments(ArgList Args) {
assert(!NumRetainedOuterLevels &&
@@ -121,27 +144,29 @@ namespace clang {
TemplateArgumentLists.push_back(Args);
}
- /// \brief Add an outermost level that we are not substituting. We have no
+ /// Add an outermost level that we are not substituting. We have no
/// arguments at this level, and do not remove it from the depth of inner
/// template parameters that we instantiate.
void addOuterRetainedLevel() {
++NumRetainedOuterLevels;
}
- /// \brief Retrieve the innermost template argument list.
- const ArgList &getInnermost() const {
+ /// Retrieve the innermost template argument list.
+ const ArgList &getInnermost() const {
return TemplateArgumentLists.front();
}
};
- /// \brief The context in which partial ordering of function templates occurs.
+ /// The context in which partial ordering of function templates occurs.
enum TPOC {
- /// \brief Partial ordering of function templates for a function call.
+ /// Partial ordering of function templates for a function call.
TPOC_Call,
- /// \brief Partial ordering of function templates for a call to a
+
+ /// Partial ordering of function templates for a call to a
/// conversion function.
TPOC_Conversion,
- /// \brief Partial ordering of function templates in other contexts, e.g.,
+
+ /// Partial ordering of function templates in other contexts, e.g.,
/// taking the address of a function template or matching a function
/// template specialization to a function template.
TPOC_Other
@@ -153,47 +178,48 @@ namespace clang {
// making Sema.h declare things as enums).
class TemplatePartialOrderingContext {
TPOC Value;
+
public:
TemplatePartialOrderingContext(TPOC Value) : Value(Value) {}
+
operator TPOC() const { return Value; }
};
- /// \brief Captures a template argument whose value has been deduced
+ /// Captures a template argument whose value has been deduced
/// via c++ template argument deduction.
class DeducedTemplateArgument : public TemplateArgument {
- /// \brief For a non-type template argument, whether the value was
+ /// For a non-type template argument, whether the value was
/// deduced from an array bound.
- bool DeducedFromArrayBound;
+ bool DeducedFromArrayBound = false;
public:
- DeducedTemplateArgument()
- : TemplateArgument(), DeducedFromArrayBound(false) { }
+ DeducedTemplateArgument() = default;
DeducedTemplateArgument(const TemplateArgument &Arg,
bool DeducedFromArrayBound = false)
- : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
+ : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {}
- /// \brief Construct an integral non-type template argument that
+ /// Construct an integral non-type template argument that
/// has been deduced, possibly from an array bound.
DeducedTemplateArgument(ASTContext &Ctx,
const llvm::APSInt &Value,
QualType ValueType,
bool DeducedFromArrayBound)
- : TemplateArgument(Ctx, Value, ValueType),
- DeducedFromArrayBound(DeducedFromArrayBound) { }
+ : TemplateArgument(Ctx, Value, ValueType),
+ DeducedFromArrayBound(DeducedFromArrayBound) {}
- /// \brief For a non-type template argument, determine whether the
+ /// For a non-type template argument, determine whether the
/// template argument was deduced from an array bound.
bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
- /// \brief Specify whether the given non-type template argument
+ /// Specify whether the given non-type template argument
/// was deduced from an array bound.
void setDeducedFromArrayBound(bool Deduced) {
DeducedFromArrayBound = Deduced;
}
};
- /// \brief A stack-allocated class that identifies which local
+ /// A stack-allocated class that identifies which local
/// variable declaration instantiations are present in this scope.
///
/// A new instance of this class type will be created whenever we
@@ -201,19 +227,19 @@ namespace clang {
/// set of parameter declarations.
class LocalInstantiationScope {
public:
- /// \brief A set of declarations.
- typedef SmallVector<ParmVarDecl *, 4> DeclArgumentPack;
+ /// A set of declarations.
+ using DeclArgumentPack = SmallVector<ParmVarDecl *, 4>;
private:
- /// \brief Reference to the semantic analysis that is performing
+ /// Reference to the semantic analysis that is performing
/// this template instantiation.
Sema &SemaRef;
- typedef llvm::SmallDenseMap<
- const Decl *, llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>
- LocalDeclsMap;
+ using LocalDeclsMap =
+ llvm::SmallDenseMap<const Decl *,
+ llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>;
- /// \brief A mapping from local declarations that occur
+ /// A mapping from local declarations that occur
/// within a template to their instantiations.
///
/// This mapping is used during instantiation to keep track of,
@@ -233,55 +259,52 @@ namespace clang {
/// pointer.
LocalDeclsMap LocalDecls;
- /// \brief The set of argument packs we've allocated.
+ /// The set of argument packs we've allocated.
SmallVector<DeclArgumentPack *, 1> ArgumentPacks;
- /// \brief The outer scope, which contains local variable
+ /// The outer scope, which contains local variable
/// definitions from some other instantiation (that may not be
/// relevant to this particular scope).
LocalInstantiationScope *Outer;
- /// \brief Whether we have already exited this scope.
- bool Exited;
+ /// Whether we have already exited this scope.
+ bool Exited = false;
- /// \brief Whether to combine this scope with the outer scope, such that
+ /// Whether to combine this scope with the outer scope, such that
/// lookup will search our outer scope.
bool CombineWithOuterScope;
- /// \brief If non-NULL, the template parameter pack that has been
+ /// If non-NULL, the template parameter pack that has been
/// partially substituted per C++0x [temp.arg.explicit]p9.
- NamedDecl *PartiallySubstitutedPack;
+ NamedDecl *PartiallySubstitutedPack = nullptr;
- /// \brief If \c PartiallySubstitutedPack is non-null, the set of
+ /// If \c PartiallySubstitutedPack is non-null, the set of
/// explicitly-specified template arguments in that pack.
const TemplateArgument *ArgsInPartiallySubstitutedPack;
- /// \brief If \c PartiallySubstitutedPack, the number of
+ /// If \c PartiallySubstitutedPack, the number of
/// explicitly-specified template arguments in
/// ArgsInPartiallySubstitutedPack.
unsigned NumArgsInPartiallySubstitutedPack;
- // This class is non-copyable
- LocalInstantiationScope(
- const LocalInstantiationScope &) = delete;
- void operator=(const LocalInstantiationScope &) = delete;
-
public:
LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
- : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
- Exited(false), CombineWithOuterScope(CombineWithOuterScope),
- PartiallySubstitutedPack(nullptr)
- {
+ : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
+ CombineWithOuterScope(CombineWithOuterScope) {
SemaRef.CurrentInstantiationScope = this;
}
+ LocalInstantiationScope(const LocalInstantiationScope &) = delete;
+ LocalInstantiationScope &
+ operator=(const LocalInstantiationScope &) = delete;
+
~LocalInstantiationScope() {
Exit();
}
const Sema &getSema() const { return SemaRef; }
- /// \brief Exit this local instantiation scope early.
+ /// Exit this local instantiation scope early.
void Exit() {
if (Exited)
return;
@@ -293,7 +316,7 @@ namespace clang {
Exited = true;
}
- /// \brief Clone this scope, and all outer scopes, down to the given
+ /// Clone this scope, and all outer scopes, down to the given
/// outermost scope.
LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) {
if (this == Outermost) return this;
@@ -333,7 +356,7 @@ namespace clang {
return newScope;
}
- /// \brief deletes the given scope, and all otuer scopes, down to the
+ /// deletes the given scope, and all otuer scopes, down to the
/// given outermost scope.
static void deleteScopes(LocalInstantiationScope *Scope,
LocalInstantiationScope *Outermost) {
@@ -344,7 +367,7 @@ namespace clang {
}
}
- /// \brief Find the instantiation of the declaration D within the current
+ /// Find the instantiation of the declaration D within the current
/// instantiation scope.
///
/// \param D The declaration whose instantiation we are searching for.
@@ -359,7 +382,7 @@ namespace clang {
void InstantiatedLocalPackArg(const Decl *D, ParmVarDecl *Inst);
void MakeInstantiatedLocalArgPack(const Decl *D);
- /// \brief Note that the given parameter pack has been partially substituted
+ /// Note that the given parameter pack has been partially substituted
/// via explicit specification of template arguments
/// (C++0x [temp.arg.explicit]p9).
///
@@ -375,7 +398,7 @@ namespace clang {
const TemplateArgument *ExplicitArgs,
unsigned NumExplicitArgs);
- /// \brief Reset the partially-substituted pack when it is no longer of
+ /// Reset the partially-substituted pack when it is no longer of
/// interest.
void ResetPartiallySubstitutedPack() {
assert(PartiallySubstitutedPack && "No partially-substituted pack");
@@ -384,7 +407,7 @@ namespace clang {
NumArgsInPartiallySubstitutedPack = 0;
}
- /// \brief Retrieve the partially-substitued template parameter pack.
+ /// Retrieve the partially-substitued template parameter pack.
///
/// If there is no partially-substituted parameter pack, returns NULL.
NamedDecl *
@@ -399,17 +422,17 @@ namespace clang {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex;
DeclContext *Owner;
const MultiLevelTemplateArgumentList &TemplateArgs;
- Sema::LateInstantiatedAttrVec* LateAttrs;
- LocalInstantiationScope *StartingScope;
+ Sema::LateInstantiatedAttrVec* LateAttrs = nullptr;
+ LocalInstantiationScope *StartingScope = nullptr;
- /// \brief A list of out-of-line class template partial
+ /// A list of out-of-line class template partial
/// specializations that will need to be instantiated after the
/// enclosing class's instantiation is complete.
SmallVector<std::pair<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *>, 4>
OutOfLinePartialSpecs;
- /// \brief A list of out-of-line variable template partial
+ /// A list of out-of-line variable template partial
/// specializations that will need to be instantiated after the
/// enclosing variable's instantiation is complete.
/// FIXME: Verify that this is needed.
@@ -420,10 +443,9 @@ namespace clang {
public:
TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
const MultiLevelTemplateArgumentList &TemplateArgs)
- : SemaRef(SemaRef),
- SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
- Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(nullptr),
- StartingScope(nullptr) {}
+ : SemaRef(SemaRef),
+ SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
+ Owner(Owner), TemplateArgs(TemplateArgs) {}
// Define all the decl visitors using DeclNodes.inc
#define DECL(DERIVED, BASE) \
@@ -476,17 +498,13 @@ namespace clang {
LocalInstantiationScope *getStartingScope() const { return StartingScope; }
- typedef
- SmallVectorImpl<std::pair<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *> >
- ::iterator
- delayed_partial_spec_iterator;
+ using delayed_partial_spec_iterator = SmallVectorImpl<std::pair<
+ ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator;
- typedef SmallVectorImpl<std::pair<
- VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> >::iterator
- delayed_var_partial_spec_iterator;
+ using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair<
+ VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator;
- /// \brief Return an iterator to the beginning of the set of
+ /// Return an iterator to the beginning of the set of
/// "delayed" partial specializations, which must be passed to
/// InstantiateClassTemplatePartialSpecialization once the class
/// definition has been completed.
@@ -498,7 +516,7 @@ namespace clang {
return OutOfLineVarPartialSpecs.begin();
}
- /// \brief Return an iterator to the end of the set of
+ /// Return an iterator to the end of the set of
/// "delayed" partial specializations, which must be passed to
/// InstantiateClassTemplatePartialSpecialization once the class
/// definition has been completed.
@@ -545,6 +563,7 @@ namespace clang {
Decl *instantiateUnresolvedUsingDecl(T *D,
bool InstantiatingPackElement = false);
};
-}
+
+} // namespace clang
#endif // LLVM_CLANG_SEMA_TEMPLATE_H
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
index cd9ed6abfaf9d..93395b4945d5b 100644
--- a/include/clang/Sema/TemplateDeduction.h
+++ b/include/clang/Sema/TemplateDeduction.h
@@ -1,80 +1,95 @@
-//===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===/
+//===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//===----------------------------------------------------------------------===/
//
-// This file provides types used with Sema's template argument deduction
+//===----------------------------------------------------------------------===//
+//
+// This file provides types used with Sema's template argument deduction
// routines.
//
-//===----------------------------------------------------------------------===/
+//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
#define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
+#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/TemplateBase.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+#include <cstddef>
+#include <utility>
namespace clang {
+class Decl;
struct DeducedPack;
-class TemplateArgumentList;
class Sema;
namespace sema {
-/// \brief Provides information about an attempted template argument
+/// Provides information about an attempted template argument
/// deduction, whose success or failure was described by a
/// TemplateDeductionResult value.
class TemplateDeductionInfo {
- /// \brief The deduced template argument list.
- ///
- TemplateArgumentList *Deduced;
+ /// The deduced template argument list.
+ TemplateArgumentList *Deduced = nullptr;
- /// \brief The source location at which template argument
+ /// The source location at which template argument
/// deduction is occurring.
SourceLocation Loc;
- /// \brief Have we suppressed an error during deduction?
- bool HasSFINAEDiagnostic;
+ /// Have we suppressed an error during deduction?
+ bool HasSFINAEDiagnostic = false;
- /// \brief The template parameter depth for which we're performing deduction.
+ /// The template parameter depth for which we're performing deduction.
unsigned DeducedDepth;
- /// \brief Warnings (and follow-on notes) that were suppressed due to
+ /// The number of parameters with explicitly-specified template arguments,
+ /// up to and including the partially-specified pack (if any).
+ unsigned ExplicitArgs = 0;
+
+ /// Warnings (and follow-on notes) that were suppressed due to
/// SFINAE while performing template argument deduction.
SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
- TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
- void operator=(const TemplateDeductionInfo &) = delete;
-
public:
TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0)
- : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
- DeducedDepth(DeducedDepth), CallArgIndex(0) {}
+ : Loc(Loc), DeducedDepth(DeducedDepth) {}
+ TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
+ TemplateDeductionInfo &operator=(const TemplateDeductionInfo &) = delete;
- /// \brief Returns the location at which template argument is
+ /// Returns the location at which template argument is
/// occurring.
SourceLocation getLocation() const {
return Loc;
}
- /// \brief The depth of template parameters for which deduction is being
+ /// The depth of template parameters for which deduction is being
/// performed.
unsigned getDeducedDepth() const {
return DeducedDepth;
}
- /// \brief Take ownership of the deduced template argument list.
+ /// Get the number of explicitly-specified arguments.
+ unsigned getNumExplicitArgs() const {
+ return ExplicitArgs;
+ }
+
+ /// Take ownership of the deduced template argument list.
TemplateArgumentList *take() {
TemplateArgumentList *Result = Deduced;
Deduced = nullptr;
return Result;
}
- /// \brief Take ownership of the SFINAE diagnostic.
+ /// Take ownership of the SFINAE diagnostic.
void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
assert(HasSFINAEDiagnostic);
PD.first = SuppressedDiagnostics.front().first;
@@ -82,7 +97,7 @@ public:
clearSFINAEDiagnostic();
}
- /// \brief Discard any SFINAE diagnostics.
+ /// Discard any SFINAE diagnostics.
void clearSFINAEDiagnostic() {
SuppressedDiagnostics.clear();
HasSFINAEDiagnostic = false;
@@ -94,18 +109,25 @@ public:
return SuppressedDiagnostics.front();
}
- /// \brief Provide a new template argument list that contains the
+ /// Provide an initial template argument list that contains the
+ /// explicitly-specified arguments.
+ void setExplicitArgs(TemplateArgumentList *NewDeduced) {
+ Deduced = NewDeduced;
+ ExplicitArgs = Deduced->size();
+ }
+
+ /// Provide a new template argument list that contains the
/// results of template argument deduction.
void reset(TemplateArgumentList *NewDeduced) {
Deduced = NewDeduced;
}
- /// \brief Is a SFINAE diagnostic available?
+ /// Is a SFINAE diagnostic available?
bool hasSFINAEDiagnostic() const {
return HasSFINAEDiagnostic;
}
- /// \brief Set the diagnostic which caused the SFINAE failure.
+ /// Set the diagnostic which caused the SFINAE failure.
void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
// Only collect the first diagnostic.
if (HasSFINAEDiagnostic)
@@ -115,7 +137,7 @@ public:
HasSFINAEDiagnostic = true;
}
- /// \brief Add a new diagnostic to the set of diagnostics
+ /// Add a new diagnostic to the set of diagnostics
void addSuppressedDiagnostic(SourceLocation Loc,
PartialDiagnostic PD) {
if (HasSFINAEDiagnostic)
@@ -123,19 +145,18 @@ public:
SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
}
- /// \brief Iterator over the set of suppressed diagnostics.
- typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator
- diag_iterator;
+ /// Iterator over the set of suppressed diagnostics.
+ using diag_iterator = SmallVectorImpl<PartialDiagnosticAt>::const_iterator;
- /// \brief Returns an iterator at the beginning of the sequence of suppressed
+ /// Returns an iterator at the beginning of the sequence of suppressed
/// diagnostics.
diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
- /// \brief Returns an iterator at the end of the sequence of suppressed
+ /// Returns an iterator at the end of the sequence of suppressed
/// diagnostics.
diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
- /// \brief The template parameter to which a template argument
+ /// The template parameter to which a template argument
/// deduction failure refers.
///
/// Depending on the result of template argument deduction, this
@@ -144,16 +165,22 @@ public:
/// TDK_Incomplete: this is the first template parameter whose
/// corresponding template argument was not deduced.
///
+ /// TDK_IncompletePack: this is the expanded parameter pack for
+ /// which we deduced too few arguments.
+ ///
/// TDK_Inconsistent: this is the template parameter for which
/// two different template argument values were deduced.
TemplateParameter Param;
- /// \brief The first template argument to which the template
+ /// The first template argument to which the template
/// argument deduction failure refers.
///
/// Depending on the result of the template argument deduction,
/// this template argument may have different meanings:
///
+ /// TDK_IncompletePack: this is the number of arguments we deduced
+ /// for the pack.
+ ///
/// TDK_Inconsistent: this argument is the first value deduced
/// for the corresponding template parameter.
///
@@ -167,7 +194,7 @@ public:
/// of the deduction, directly provided in the source code.
TemplateArgument FirstArg;
- /// \brief The second template argument to which the template
+ /// The second template argument to which the template
/// argument deduction failure refers.
///
/// TDK_Inconsistent: this argument is the second value deduced
@@ -181,20 +208,20 @@ public:
/// FIXME: Finish documenting this.
TemplateArgument SecondArg;
- /// \brief The index of the function argument that caused a deduction
+ /// The index of the function argument that caused a deduction
/// failure.
///
/// TDK_DeducedMismatch: this is the index of the argument that had a
/// different argument type from its substituted parameter type.
- unsigned CallArgIndex;
+ unsigned CallArgIndex = 0;
- /// \brief Information on packs that we're currently expanding.
+ /// Information on packs that we're currently expanding.
///
/// FIXME: This should be kept internal to SemaTemplateDeduction.
SmallVector<DeducedPack *, 8> PendingDeducedPacks;
};
-} // end namespace sema
+} // namespace sema
/// A structure used to record information about a failed
/// template argument deduction, for diagnosis.
@@ -202,41 +229,41 @@ struct DeductionFailureInfo {
/// A Sema::TemplateDeductionResult.
unsigned Result : 8;
- /// \brief Indicates whether a diagnostic is stored in Diagnostic.
+ /// Indicates whether a diagnostic is stored in Diagnostic.
unsigned HasDiagnostic : 1;
- /// \brief Opaque pointer containing additional data about
+ /// Opaque pointer containing additional data about
/// this deduction failure.
void *Data;
- /// \brief A diagnostic indicating why deduction failed.
+ /// A diagnostic indicating why deduction failed.
alignas(PartialDiagnosticAt) char Diagnostic[sizeof(PartialDiagnosticAt)];
- /// \brief Retrieve the diagnostic which caused this deduction failure,
+ /// Retrieve the diagnostic which caused this deduction failure,
/// if any.
PartialDiagnosticAt *getSFINAEDiagnostic();
- /// \brief Retrieve the template parameter this deduction failure
+ /// Retrieve the template parameter this deduction failure
/// refers to, if any.
TemplateParameter getTemplateParameter();
- /// \brief Retrieve the template argument list associated with this
+ /// Retrieve the template argument list associated with this
/// deduction failure, if any.
TemplateArgumentList *getTemplateArgumentList();
- /// \brief Return the first template argument this deduction failure
+ /// Return the first template argument this deduction failure
/// refers to, if any.
const TemplateArgument *getFirstArg();
- /// \brief Return the second template argument this deduction failure
+ /// Return the second template argument this deduction failure
/// refers to, if any.
const TemplateArgument *getSecondArg();
- /// \brief Return the index of the call argument that this deduction
+ /// Return the index of the call argument that this deduction
/// failure refers to, if any.
llvm::Optional<unsigned> getCallArgIndex();
- /// \brief Free any memory associated with this deduction failure.
+ /// Free any memory associated with this deduction failure.
void Destroy();
};
@@ -248,7 +275,7 @@ struct DeductionFailureInfo {
/// TODO: In the future, we may need to unify/generalize this with
/// OverloadCandidate.
struct TemplateSpecCandidate {
- /// \brief The declaration that was looked up, together with its access.
+ /// The declaration that was looked up, together with its access.
/// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl.
DeclAccessPair FoundDecl;
@@ -276,36 +303,37 @@ struct TemplateSpecCandidate {
class TemplateSpecCandidateSet {
SmallVector<TemplateSpecCandidate, 16> Candidates;
SourceLocation Loc;
+
// Stores whether we're taking the address of these candidates. This helps us
// produce better error messages when dealing with the pass_object_size
// attribute on parameters.
bool ForTakingAddress;
- TemplateSpecCandidateSet(
- const TemplateSpecCandidateSet &) = delete;
- void operator=(const TemplateSpecCandidateSet &) = delete;
-
void destroyCandidates();
public:
TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false)
: Loc(Loc), ForTakingAddress(ForTakingAddress) {}
+ TemplateSpecCandidateSet(const TemplateSpecCandidateSet &) = delete;
+ TemplateSpecCandidateSet &
+ operator=(const TemplateSpecCandidateSet &) = delete;
~TemplateSpecCandidateSet() { destroyCandidates(); }
SourceLocation getLocation() const { return Loc; }
- /// \brief Clear out all of the candidates.
+ /// Clear out all of the candidates.
/// TODO: This may be unnecessary.
void clear();
- typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator;
+ using iterator = SmallVector<TemplateSpecCandidate, 16>::iterator;
+
iterator begin() { return Candidates.begin(); }
iterator end() { return Candidates.end(); }
size_t size() const { return Candidates.size(); }
bool empty() const { return Candidates.empty(); }
- /// \brief Add a new candidate with NumConversions conversion sequence slots
+ /// Add a new candidate with NumConversions conversion sequence slots
/// to the overload set.
TemplateSpecCandidate &addCandidate() {
Candidates.emplace_back();
@@ -319,6 +347,6 @@ public:
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
diff --git a/include/clang/Sema/TemplateInstCallback.h b/include/clang/Sema/TemplateInstCallback.h
new file mode 100644
index 0000000000000..dc729d52243c5
--- /dev/null
+++ b/include/clang/Sema/TemplateInstCallback.h
@@ -0,0 +1,83 @@
+//===- TemplateInstCallback.h - Template Instantiation Callback - 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 TemplateInstantiationCallback class, which is the
+// base class for callbacks that will be notified at template instantiations.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TEMPLATE_INST_CALLBACK_H
+#define LLVM_CLANG_TEMPLATE_INST_CALLBACK_H
+
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+
+/// This is a base class for callbacks that will be notified at every
+/// template instantiation.
+class TemplateInstantiationCallback {
+public:
+ virtual ~TemplateInstantiationCallback() = default;
+
+ /// Called before doing AST-parsing.
+ virtual void initialize(const Sema &TheSema) = 0;
+
+ /// Called after AST-parsing is completed.
+ virtual void finalize(const Sema &TheSema) = 0;
+
+ /// Called when instantiation of a template just began.
+ virtual void atTemplateBegin(const Sema &TheSema,
+ const Sema::CodeSynthesisContext &Inst) = 0;
+
+ /// Called when instantiation of a template is just about to end.
+ virtual void atTemplateEnd(const Sema &TheSema,
+ const Sema::CodeSynthesisContext &Inst) = 0;
+};
+
+template <class TemplateInstantiationCallbackPtrs>
+void initialize(TemplateInstantiationCallbackPtrs &Callbacks,
+ const Sema &TheSema) {
+ for (auto &C : Callbacks) {
+ if (C)
+ C->initialize(TheSema);
+ }
+}
+
+template <class TemplateInstantiationCallbackPtrs>
+void finalize(TemplateInstantiationCallbackPtrs &Callbacks,
+ const Sema &TheSema) {
+ for (auto &C : Callbacks) {
+ if (C)
+ C->finalize(TheSema);
+ }
+}
+
+template <class TemplateInstantiationCallbackPtrs>
+void atTemplateBegin(TemplateInstantiationCallbackPtrs &Callbacks,
+ const Sema &TheSema,
+ const Sema::CodeSynthesisContext &Inst) {
+ for (auto &C : Callbacks) {
+ if (C)
+ C->atTemplateBegin(TheSema, Inst);
+ }
+}
+
+template <class TemplateInstantiationCallbackPtrs>
+void atTemplateEnd(TemplateInstantiationCallbackPtrs &Callbacks,
+ const Sema &TheSema,
+ const Sema::CodeSynthesisContext &Inst) {
+ for (auto &C : Callbacks) {
+ if (C)
+ C->atTemplateEnd(TheSema, Inst);
+ }
+}
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
index 5bebe52325c63..d8fe827998454 100644
--- a/include/clang/Sema/TypoCorrection.h
+++ b/include/clang/Sema/TypoCorrection.h
@@ -1,4 +1,4 @@
-//===--- TypoCorrection.h - Class for typo correction results ---*- C++ -*-===//
+//===- TypoCorrection.h - Class for typo correction results -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,18 +15,36 @@
#ifndef LLVM_CLANG_SEMA_TYPOCORRECTION_H
#define LLVM_CLANG_SEMA_TYPOCORRECTION_H
-#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/DeclSpec.h"
-#include "clang/Sema/Ownership.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+#include <cstddef>
+#include <limits>
+#include <string>
+#include <utility>
+#include <vector>
namespace clang {
-/// @brief Simple class containing the result of Sema::CorrectTypo
+class DeclContext;
+class IdentifierInfo;
+class LangOptions;
+class MemberExpr;
+class NestedNameSpecifier;
+class Sema;
+
+/// Simple class containing the result of Sema::CorrectTypo
class TypoCorrection {
public:
// "Distance" for unusable corrections
- static const unsigned InvalidDistance = ~0U;
+ static const unsigned InvalidDistance = std::numeric_limits<unsigned>::max();
+
// The largest distance still considered valid (larger edit distances are
// mapped to InvalidDistance by getEditDistance).
static const unsigned MaximumDistance = 10000U;
@@ -43,9 +61,7 @@ public:
NestedNameSpecifier *NNS = nullptr, unsigned CharDistance = 0,
unsigned QualifierDistance = 0)
: CorrectionName(Name), CorrectionNameSpec(NNS),
- CharDistance(CharDistance), QualifierDistance(QualifierDistance),
- CallbackDistance(0), ForceSpecifierReplacement(false),
- RequiresImport(false) {
+ CharDistance(CharDistance), QualifierDistance(QualifierDistance) {
if (NameDecl)
CorrectionDecls.push_back(NameDecl);
}
@@ -53,8 +69,7 @@ public:
TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = nullptr,
unsigned CharDistance = 0)
: CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS),
- CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0),
- ForceSpecifierReplacement(false), RequiresImport(false) {
+ CharDistance(CharDistance) {
if (Name)
CorrectionDecls.push_back(Name);
}
@@ -62,24 +77,22 @@ public:
TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = nullptr,
unsigned CharDistance = 0)
: CorrectionName(Name), CorrectionNameSpec(NNS),
- CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0),
- ForceSpecifierReplacement(false), RequiresImport(false) {}
+ CharDistance(CharDistance) {}
- TypoCorrection()
- : CorrectionNameSpec(nullptr), CharDistance(0), QualifierDistance(0),
- CallbackDistance(0), ForceSpecifierReplacement(false),
- RequiresImport(false) {}
+ TypoCorrection() = default;
- /// \brief Gets the DeclarationName of the typo correction
+ /// Gets the DeclarationName of the typo correction
DeclarationName getCorrection() const { return CorrectionName; }
+
IdentifierInfo *getCorrectionAsIdentifierInfo() const {
return CorrectionName.getAsIdentifierInfo();
}
- /// \brief Gets the NestedNameSpecifier needed to use the typo correction
+ /// Gets the NestedNameSpecifier needed to use the typo correction
NestedNameSpecifier *getCorrectionSpecifier() const {
return CorrectionNameSpec;
}
+
void setCorrectionSpecifier(NestedNameSpecifier *NNS) {
CorrectionNameSpec = NNS;
ForceSpecifierReplacement = (NNS != nullptr);
@@ -110,7 +123,7 @@ public:
return (ED + CharDistanceWeight / 2) / CharDistanceWeight;
}
- /// \brief Gets the "edit distance" of the typo correction from the typo.
+ /// Gets the "edit distance" of the typo correction from the typo.
/// If Normalized is true, scale the distance down by the CharDistanceWeight
/// to return the edit distance in terms of single-character edits.
unsigned getEditDistance(bool Normalized = true) const {
@@ -129,13 +142,13 @@ public:
return Normalized ? NormalizeEditDistance(ED) : ED;
}
- /// \brief Get the correction declaration found by name lookup (before we
+ /// Get the correction declaration found by name lookup (before we
/// looked through using shadow declarations and the like).
NamedDecl *getFoundDecl() const {
return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : nullptr;
}
- /// \brief Gets the pointer to the declaration of the typo correction
+ /// Gets the pointer to the declaration of the typo correction
NamedDecl *getCorrectionDecl() const {
auto *D = getFoundDecl();
return D ? D->getUnderlyingDecl() : nullptr;
@@ -145,36 +158,37 @@ public:
return dyn_cast_or_null<DeclClass>(getCorrectionDecl());
}
- /// \brief Clears the list of NamedDecls.
+ /// Clears the list of NamedDecls.
void ClearCorrectionDecls() {
CorrectionDecls.clear();
}
- /// \brief Clears the list of NamedDecls before adding the new one.
+ /// Clears the list of NamedDecls before adding the new one.
void setCorrectionDecl(NamedDecl *CDecl) {
CorrectionDecls.clear();
addCorrectionDecl(CDecl);
}
- /// \brief Clears the list of NamedDecls and adds the given set.
+ /// Clears the list of NamedDecls and adds the given set.
void setCorrectionDecls(ArrayRef<NamedDecl*> Decls) {
CorrectionDecls.clear();
CorrectionDecls.insert(CorrectionDecls.begin(), Decls.begin(), Decls.end());
}
- /// \brief Add the given NamedDecl to the list of NamedDecls that are the
+ /// Add the given NamedDecl to the list of NamedDecls that are the
/// declarations associated with the DeclarationName of this TypoCorrection
void addCorrectionDecl(NamedDecl *CDecl);
std::string getAsString(const LangOptions &LO) const;
+
std::string getQuoted(const LangOptions &LO) const {
return "'" + getAsString(LO) + "'";
}
- /// \brief Returns whether this TypoCorrection has a non-empty DeclarationName
+ /// Returns whether this TypoCorrection has a non-empty DeclarationName
explicit operator bool() const { return bool(CorrectionName); }
- /// \brief Mark this TypoCorrection as being a keyword.
+ /// Mark this TypoCorrection as being a keyword.
/// Since addCorrectionDeclsand setCorrectionDecl don't allow NULL to be
/// added to the list of the correction's NamedDecl pointers, NULL is added
/// as the only element in the list to mark this TypoCorrection as a keyword.
@@ -214,18 +228,23 @@ public:
return CorrectionRange;
}
- typedef SmallVectorImpl<NamedDecl *>::iterator decl_iterator;
+ using decl_iterator = SmallVectorImpl<NamedDecl *>::iterator;
+
decl_iterator begin() {
return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin();
}
+
decl_iterator end() { return CorrectionDecls.end(); }
- typedef SmallVectorImpl<NamedDecl *>::const_iterator const_decl_iterator;
+
+ using const_decl_iterator = SmallVectorImpl<NamedDecl *>::const_iterator;
+
const_decl_iterator begin() const {
return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin();
}
+
const_decl_iterator end() const { return CorrectionDecls.end(); }
- /// \brief Returns whether this typo correction is correcting to a
+ /// Returns whether this typo correction is correcting to a
/// declaration that was declared in a module that has not been imported.
bool requiresImport() const { return RequiresImport; }
void setRequiresImport(bool Req) { RequiresImport = Req; }
@@ -246,19 +265,19 @@ private:
// Results.
DeclarationName CorrectionName;
- NestedNameSpecifier *CorrectionNameSpec;
+ NestedNameSpecifier *CorrectionNameSpec = nullptr;
SmallVector<NamedDecl *, 1> CorrectionDecls;
- unsigned CharDistance;
- unsigned QualifierDistance;
- unsigned CallbackDistance;
+ unsigned CharDistance = 0;
+ unsigned QualifierDistance = 0;
+ unsigned CallbackDistance = 0;
SourceRange CorrectionRange;
- bool ForceSpecifierReplacement;
- bool RequiresImport;
+ bool ForceSpecifierReplacement = false;
+ bool RequiresImport = false;
std::vector<PartialDiagnostic> ExtraDiagnostics;
};
-/// @brief Base class for callback objects used by Sema::CorrectTypo to check
+/// Base class for callback objects used by Sema::CorrectTypo to check
/// the validity of a potential typo correction.
class CorrectionCandidateCallback {
public:
@@ -266,19 +285,15 @@ public:
explicit CorrectionCandidateCallback(IdentifierInfo *Typo = nullptr,
NestedNameSpecifier *TypoNNS = nullptr)
- : WantTypeSpecifiers(true), WantExpressionKeywords(true),
- WantCXXNamedCasts(true), WantFunctionLikeCasts(true),
- WantRemainingKeywords(true), WantObjCSuper(false),
- IsObjCIvarLookup(false), IsAddressOfOperand(false), Typo(Typo),
- TypoNNS(TypoNNS) {}
+ : Typo(Typo), TypoNNS(TypoNNS) {}
- virtual ~CorrectionCandidateCallback() {}
+ virtual ~CorrectionCandidateCallback() = default;
- /// \brief Simple predicate used by the default RankCandidate to
+ /// Simple predicate used by the default RankCandidate to
/// determine whether to return an edit distance of 0 or InvalidDistance.
- /// This can be overrided by validators that only need to determine if a
+ /// This can be overridden by validators that only need to determine if a
/// candidate is viable, without ranking potentially viable candidates.
- /// Only ValidateCandidate or RankCandidate need to be overriden by a
+ /// Only ValidateCandidate or RankCandidate need to be overridden by a
/// callback wishing to check the viability of correction candidates.
/// The default predicate always returns true if the candidate is not a type
/// name or keyword, true for types if WantTypeSpecifiers is true, and true
@@ -286,7 +301,7 @@ public:
/// WantCXXNamedCasts, WantRemainingKeywords, or WantObjCSuper is true.
virtual bool ValidateCandidate(const TypoCorrection &candidate);
- /// \brief Method used by Sema::CorrectTypo to assign an "edit distance" rank
+ /// Method used by Sema::CorrectTypo to assign an "edit distance" rank
/// to a candidate (where a lower value represents a better candidate), or
/// returning InvalidDistance if the candidate is not at all viable. For
/// validation callbacks that only need to determine if a candidate is viable,
@@ -304,16 +319,16 @@ public:
// Flags for context-dependent keywords. WantFunctionLikeCasts is only
// used/meaningful when WantCXXNamedCasts is false.
// TODO: Expand these to apply to non-keywords or possibly remove them.
- bool WantTypeSpecifiers;
- bool WantExpressionKeywords;
- bool WantCXXNamedCasts;
- bool WantFunctionLikeCasts;
- bool WantRemainingKeywords;
- bool WantObjCSuper;
+ bool WantTypeSpecifiers = true;
+ bool WantExpressionKeywords = true;
+ bool WantCXXNamedCasts = true;
+ bool WantFunctionLikeCasts = true;
+ bool WantRemainingKeywords = true;
+ bool WantObjCSuper = false;
// Temporary hack for the one case where a CorrectTypoContext enum is used
// when looking up results.
- bool IsObjCIvarLookup;
- bool IsAddressOfOperand;
+ bool IsObjCIvarLookup = false;
+ bool IsAddressOfOperand = false;
protected:
bool MatchesTypo(const TypoCorrection &candidate) {
@@ -328,7 +343,7 @@ protected:
NestedNameSpecifier *TypoNNS;
};
-/// @brief Simple template class for restricting typo correction candidates
+/// Simple template class for restricting typo correction candidates
/// to ones having a single Decl* of the given type.
template <class C>
class DeclFilterCCC : public CorrectionCandidateCallback {
@@ -338,7 +353,7 @@ public:
}
};
-// @brief Callback class to limit the allowed keywords and to only accept typo
+// Callback class to limit the allowed keywords and to only accept typo
// corrections that are keywords or whose decls refer to functions (or template
// functions) that accept the given number of arguments.
class FunctionCallFilterCCC : public CorrectionCandidateCallback {
@@ -349,14 +364,14 @@ public:
bool ValidateCandidate(const TypoCorrection &candidate) override;
- private:
+private:
unsigned NumArgs;
bool HasExplicitTemplateArgs;
DeclContext *CurContext;
MemberExpr *MemberFn;
};
-// @brief Callback class that effectively disabled typo correction
+// Callback class that effectively disabled typo correction
class NoTypoCorrectionCCC : public CorrectionCandidateCallback {
public:
NoTypoCorrectionCCC() {
@@ -372,6 +387,6 @@ public:
}
};
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SEMA_TYPOCORRECTION_H
diff --git a/include/clang/Sema/Weak.h b/include/clang/Sema/Weak.h
index 9c7212e0c8eed..115e97bcd2ce7 100644
--- a/include/clang/Sema/Weak.h
+++ b/include/clang/Sema/Weak.h
@@ -21,7 +21,7 @@ namespace clang {
class IdentifierInfo;
-/// \brief Captures information about a \#pragma weak directive.
+/// Captures information about a \#pragma weak directive.
class WeakInfo {
IdentifierInfo *alias; // alias (optional)
SourceLocation loc; // for diagnostics
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 34a7bb330174b..76bc818557a96 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -31,7 +31,7 @@
namespace clang {
namespace serialization {
- /// \brief AST file major version number supported by this version of
+ /// AST file major version number supported by this version of
/// Clang.
///
/// Whenever the AST file format changes in a way that makes it
@@ -42,9 +42,9 @@ namespace serialization {
/// Version 4 of AST files also requires that the version control branch and
/// revision match exactly, since there is no backward compatibility of
/// AST files at this time.
- const unsigned VERSION_MAJOR = 6;
+ const unsigned VERSION_MAJOR = 7;
- /// \brief AST file minor version number supported by this version of
+ /// AST file minor version number supported by this version of
/// Clang.
///
/// Whenever the AST format changes in a way that is still
@@ -54,13 +54,13 @@ namespace serialization {
/// should be increased.
const unsigned VERSION_MINOR = 0;
- /// \brief An ID number that refers to an identifier in an AST file.
+ /// An ID number that refers to an identifier in an AST file.
///
/// The ID numbers of identifiers are consecutive (in order of discovery)
/// and start at 1. 0 is reserved for NULL.
using IdentifierID = uint32_t;
- /// \brief An ID number that refers to a declaration in an AST file.
+ /// An ID number that refers to a declaration in an AST file.
///
/// The ID numbers of declarations are consecutive (in order of
/// discovery), with values below NUM_PREDEF_DECL_IDS being reserved.
@@ -73,7 +73,7 @@ namespace serialization {
using LocalDeclID = DeclID;
using GlobalDeclID = DeclID;
- /// \brief An ID number that refers to a type in an AST file.
+ /// An ID number that refers to a type in an AST file.
///
/// The ID of a type is partitioned into two parts: the lower
/// three bits are used to store the const/volatile/restrict
@@ -85,7 +85,7 @@ namespace serialization {
/// other types that have serialized representations.
using TypeID = uint32_t;
- /// \brief A type index; the type ID with the qualifier bits removed.
+ /// A type index; the type ID with the qualifier bits removed.
class TypeIdx {
uint32_t Idx = 0;
@@ -131,58 +131,58 @@ namespace serialization {
}
};
- /// \brief An ID number that refers to an identifier in an AST file.
+ /// An ID number that refers to an identifier in an AST file.
using IdentID = uint32_t;
- /// \brief The number of predefined identifier IDs.
+ /// The number of predefined identifier IDs.
const unsigned int NUM_PREDEF_IDENT_IDS = 1;
- /// \brief An ID number that refers to a macro in an AST file.
+ /// An ID number that refers to a macro in an AST file.
using MacroID = uint32_t;
- /// \brief A global ID number that refers to a macro in an AST file.
+ /// A global ID number that refers to a macro in an AST file.
using GlobalMacroID = uint32_t;
- /// \brief A local to a module ID number that refers to a macro in an
+ /// A local to a module ID number that refers to a macro in an
/// AST file.
using LocalMacroID = uint32_t;
- /// \brief The number of predefined macro IDs.
+ /// The number of predefined macro IDs.
const unsigned int NUM_PREDEF_MACRO_IDS = 1;
- /// \brief An ID number that refers to an ObjC selector in an AST file.
+ /// An ID number that refers to an ObjC selector in an AST file.
using SelectorID = uint32_t;
- /// \brief The number of predefined selector IDs.
+ /// The number of predefined selector IDs.
const unsigned int NUM_PREDEF_SELECTOR_IDS = 1;
- /// \brief An ID number that refers to a set of CXXBaseSpecifiers in an
+ /// An ID number that refers to a set of CXXBaseSpecifiers in an
/// AST file.
using CXXBaseSpecifiersID = uint32_t;
- /// \brief An ID number that refers to a list of CXXCtorInitializers in an
+ /// An ID number that refers to a list of CXXCtorInitializers in an
/// AST file.
using CXXCtorInitializersID = uint32_t;
- /// \brief An ID number that refers to an entity in the detailed
+ /// An ID number that refers to an entity in the detailed
/// preprocessing record.
using PreprocessedEntityID = uint32_t;
- /// \brief An ID number that refers to a submodule in a module file.
+ /// An ID number that refers to a submodule in a module file.
using SubmoduleID = uint32_t;
- /// \brief The number of predefined submodule IDs.
+ /// The number of predefined submodule IDs.
const unsigned int NUM_PREDEF_SUBMODULE_IDS = 1;
- /// \brief Source range/offset of a preprocessed entity.
+ /// Source range/offset of a preprocessed entity.
struct PPEntityOffset {
- /// \brief Raw source location of beginning of range.
+ /// Raw source location of beginning of range.
unsigned Begin;
- /// \brief Raw source location of end of range.
+ /// Raw source location of end of range.
unsigned End;
- /// \brief Offset in the AST file.
+ /// Offset in the AST file.
uint32_t BitOffset;
PPEntityOffset(SourceRange R, uint32_t BitOffset)
@@ -198,12 +198,31 @@ namespace serialization {
}
};
- /// \brief Source range/offset of a preprocessed entity.
+ /// Source range of a skipped preprocessor region
+ struct PPSkippedRange {
+ /// Raw source location of beginning of range.
+ unsigned Begin;
+ /// Raw source location of end of range.
+ unsigned End;
+
+ PPSkippedRange(SourceRange R)
+ : Begin(R.getBegin().getRawEncoding()),
+ End(R.getEnd().getRawEncoding()) { }
+
+ SourceLocation getBegin() const {
+ return SourceLocation::getFromRawEncoding(Begin);
+ }
+ SourceLocation getEnd() const {
+ return SourceLocation::getFromRawEncoding(End);
+ }
+ };
+
+ /// Source range/offset of a preprocessed entity.
struct DeclOffset {
- /// \brief Raw source location.
+ /// Raw source location.
unsigned Loc = 0;
- /// \brief Offset in the AST file.
+ /// Offset in the AST file.
uint32_t BitOffset = 0;
DeclOffset() = default;
@@ -219,56 +238,56 @@ namespace serialization {
}
};
- /// \brief The number of predefined preprocessed entity IDs.
+ /// The number of predefined preprocessed entity IDs.
const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1;
- /// \brief Describes the various kinds of blocks that occur within
+ /// Describes the various kinds of blocks that occur within
/// an AST file.
enum BlockIDs {
- /// \brief The AST block, which acts as a container around the
+ /// The AST block, which acts as a container around the
/// full AST block.
AST_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,
- /// \brief The block containing information about the source
+ /// The block containing information about the source
/// manager.
SOURCE_MANAGER_BLOCK_ID,
- /// \brief The block containing information about the
+ /// The block containing information about the
/// preprocessor.
PREPROCESSOR_BLOCK_ID,
- /// \brief The block containing the definitions of all of the
+ /// The block containing the definitions of all of the
/// types and decls used within the AST file.
DECLTYPES_BLOCK_ID,
- /// \brief The block containing the detailed preprocessing record.
+ /// The block containing the detailed preprocessing record.
PREPROCESSOR_DETAIL_BLOCK_ID,
- /// \brief The block containing the submodule structure.
+ /// The block containing the submodule structure.
SUBMODULE_BLOCK_ID,
- /// \brief The block containing comments.
+ /// The block containing comments.
COMMENTS_BLOCK_ID,
- /// \brief The control block, which contains all of the
+ /// The control block, which contains all of the
/// information that needs to be validated prior to committing
/// to loading the AST file.
CONTROL_BLOCK_ID,
- /// \brief The block of input files, which were used as inputs
+ /// The block of input files, which were used as inputs
/// to create this AST file.
///
/// This block is part of the control block.
INPUT_FILES_BLOCK_ID,
- /// \brief The block of configuration options, used to check that
+ /// The block of configuration options, used to check that
/// a module is being used in a configuration compatible with the
/// configuration in which it was built.
///
/// This block is part of the control block.
OPTIONS_BLOCK_ID,
- /// \brief A block containing a module file extension.
+ /// A block containing a module file extension.
EXTENSION_BLOCK_ID,
/// A block with unhashed content.
@@ -278,47 +297,47 @@ namespace serialization {
UNHASHED_CONTROL_BLOCK_ID,
};
- /// \brief Record types that occur within the control block.
+ /// Record types that occur within the control block.
enum ControlRecordTypes {
- /// \brief AST file metadata, including the AST file version number
+ /// AST file metadata, including the AST file version number
/// and information about the compiler used to build this AST file.
METADATA = 1,
- /// \brief Record code for the list of other AST files imported by
+ /// Record code for the list of other AST files imported by
/// this AST file.
IMPORTS,
- /// \brief Record code for the original file that was used to
+ /// Record code for the original file that was used to
/// generate the AST file, including both its file ID and its
/// name.
ORIGINAL_FILE,
- /// \brief The directory that the PCH was originally created in.
+ /// The directory that the PCH was originally created in.
ORIGINAL_PCH_DIR,
- /// \brief Record code for file ID of the file or buffer that was used to
+ /// Record code for file ID of the file or buffer that was used to
/// generate the AST file.
ORIGINAL_FILE_ID,
- /// \brief Offsets into the input-files block where input files
+ /// Offsets into the input-files block where input files
/// reside.
INPUT_FILE_OFFSETS,
- /// \brief Record code for the module name.
+ /// Record code for the module name.
MODULE_NAME,
- /// \brief Record code for the module map file that was used to build this
+ /// Record code for the module map file that was used to build this
/// AST file.
MODULE_MAP_FILE,
- /// \brief Record code for the module build directory.
+ /// Record code for the module build directory.
MODULE_DIRECTORY,
};
- /// \brief Record types that occur within the options block inside
+ /// Record types that occur within the options block inside
/// the control block.
enum OptionsRecordTypes {
- /// \brief Record code for the language options table.
+ /// Record code for the language options table.
///
/// The record with this code contains the contents of the
/// LangOptions structure. We serialize the entire contents of
@@ -326,16 +345,16 @@ namespace serialization {
/// actually important to check.
LANGUAGE_OPTIONS = 1,
- /// \brief Record code for the target options table.
+ /// Record code for the target options table.
TARGET_OPTIONS,
- /// \brief Record code for the filesystem options table.
+ /// Record code for the filesystem options table.
FILE_SYSTEM_OPTIONS,
- /// \brief Record code for the headers search options table.
+ /// Record code for the headers search options table.
HEADER_SEARCH_OPTIONS,
- /// \brief Record code for the preprocessor options table.
+ /// Record code for the preprocessor options table.
PREPROCESSOR_OPTIONS,
};
@@ -351,7 +370,7 @@ namespace serialization {
DIAG_PRAGMA_MAPPINGS,
};
- /// \brief Record code for extension blocks.
+ /// Record code for extension blocks.
enum ExtensionBlockRecordTypes {
/// Metadata describing this particular extension.
EXTENSION_METADATA = 1,
@@ -360,16 +379,16 @@ namespace serialization {
FIRST_EXTENSION_RECORD_ID = 4
};
- /// \brief Record types that occur within the input-files block
+ /// Record types that occur within the input-files block
/// inside the control block.
enum InputFileRecordTypes {
- /// \brief An input file.
+ /// An input file.
INPUT_FILE = 1
};
- /// \brief Record types that occur within the AST block itself.
+ /// Record types that occur within the AST block itself.
enum ASTRecordTypes {
- /// \brief Record code for the offsets of each type.
+ /// Record code for the offsets of each type.
///
/// The TYPE_OFFSET constant describes the record that occurs
/// within the AST block. The record itself is an array of offsets that
@@ -383,7 +402,7 @@ namespace serialization {
/// corresponding record within the DECLTYPES_BLOCK_ID block.
TYPE_OFFSET = 1,
- /// \brief Record code for the offsets of each decl.
+ /// Record code for the offsets of each decl.
///
/// The DECL_OFFSET constant describes the record that occurs
/// within the block identified by DECL_OFFSETS_BLOCK_ID within
@@ -395,7 +414,7 @@ namespace serialization {
/// reserved for the translation unit declaration.
DECL_OFFSET = 2,
- /// \brief Record code for the table of offsets of each
+ /// Record code for the table of offsets of each
/// identifier ID.
///
/// The offset table contains offsets into the blob stored in
@@ -403,12 +422,12 @@ namespace serialization {
/// NULL-terminated string that corresponds to that identifier.
IDENTIFIER_OFFSET = 3,
- /// \brief This is so that older clang versions, before the introduction
+ /// This is so that older clang versions, before the introduction
/// of the control block, can read and reject the newer PCH format.
/// *DON'T CHANGE THIS NUMBER*.
METADATA_OLD_FORMAT = 4,
- /// \brief Record code for the identifier table.
+ /// Record code for the identifier table.
///
/// The identifier table is a simple blob that contains
/// NULL-terminated strings for all of the identifiers
@@ -422,7 +441,7 @@ namespace serialization {
/// IDs).
IDENTIFIER_TABLE = 5,
- /// \brief Record code for the array of eagerly deserialized decls.
+ /// Record code for the array of eagerly deserialized decls.
///
/// The AST file contains a list of all of the declarations that should be
/// eagerly deserialized present within the parsed headers, stored as an
@@ -432,7 +451,7 @@ namespace serialization {
/// program (e.g., for code generation).
EAGERLY_DESERIALIZED_DECLS = 6,
- /// \brief Record code for the set of non-builtin, special
+ /// Record code for the set of non-builtin, special
/// types.
///
/// This record contains the type IDs for the various type nodes
@@ -441,31 +460,31 @@ namespace serialization {
/// offsets into this record.
SPECIAL_TYPES = 7,
- /// \brief Record code for the extra statistics we gather while
+ /// Record code for the extra statistics we gather while
/// generating an AST file.
STATISTICS = 8,
- /// \brief Record code for the array of tentative definitions.
+ /// Record code for the array of tentative definitions.
TENTATIVE_DEFINITIONS = 9,
// ID 10 used to be for a list of extern "C" declarations.
- /// \brief Record code for the table of offsets into the
+ /// Record code for the table of offsets into the
/// Objective-C method pool.
SELECTOR_OFFSETS = 11,
- /// \brief Record code for the Objective-C method pool,
+ /// Record code for the Objective-C method pool,
METHOD_POOL = 12,
- /// \brief The value of the next __COUNTER__ to dispense.
+ /// The value of the next __COUNTER__ to dispense.
/// [PP_COUNTER_VALUE, Val]
PP_COUNTER_VALUE = 13,
- /// \brief Record code for the table of offsets into the block
+ /// Record code for the table of offsets into the block
/// of source-location information.
SOURCE_LOCATION_OFFSETS = 14,
- /// \brief Record code for the set of source location entries
+ /// Record code for the set of source location entries
/// that need to be preloaded by the AST reader.
///
/// This set contains the source location entry for the
@@ -473,47 +492,47 @@ namespace serialization {
/// preloaded.
SOURCE_LOCATION_PRELOADS = 15,
- /// \brief Record code for the set of ext_vector type names.
+ /// Record code for the set of ext_vector type names.
EXT_VECTOR_DECLS = 16,
- /// \brief Record code for the array of unused file scoped decls.
+ /// Record code for the array of unused file scoped decls.
UNUSED_FILESCOPED_DECLS = 17,
- /// \brief Record code for the table of offsets to entries in the
+ /// Record code for the table of offsets to entries in the
/// preprocessing record.
PPD_ENTITIES_OFFSETS = 18,
- /// \brief Record code for the array of VTable uses.
+ /// Record code for the array of VTable uses.
VTABLE_USES = 19,
// ID 20 used to be for a list of dynamic classes.
- /// \brief Record code for referenced selector pool.
+ /// Record code for referenced selector pool.
REFERENCED_SELECTOR_POOL = 21,
- /// \brief Record code for an update to the TU's lexically contained
+ /// Record code for an update to the TU's lexically contained
/// declarations.
TU_UPDATE_LEXICAL = 22,
// ID 23 used to be for a list of local redeclarations.
- /// \brief Record code for declarations that Sema keeps references of.
+ /// Record code for declarations that Sema keeps references of.
SEMA_DECL_REFS = 24,
- /// \brief Record code for weak undeclared identifiers.
+ /// Record code for weak undeclared identifiers.
WEAK_UNDECLARED_IDENTIFIERS = 25,
- /// \brief Record code for pending implicit instantiations.
+ /// Record code for pending implicit instantiations.
PENDING_IMPLICIT_INSTANTIATIONS = 26,
// ID 27 used to be for a list of replacement decls.
- /// \brief Record code for an update to a decl context's lookup table.
+ /// Record code for an update to a decl context's lookup table.
///
/// In practice, this should only be used for the TU and namespaces.
UPDATE_VISIBLE = 28,
- /// \brief Record for offsets of DECL_UPDATES records for declarations
+ /// Record for offsets of DECL_UPDATES records for declarations
/// that were modified after being deserialized and need updates.
DECL_UPDATE_OFFSETS = 29,
@@ -524,242 +543,245 @@ namespace serialization {
// ID 32 used to be the code for \#pragma diagnostic mappings.
- /// \brief Record code for special CUDA declarations.
+ /// Record code for special CUDA declarations.
CUDA_SPECIAL_DECL_REFS = 33,
- /// \brief Record code for header search information.
+ /// Record code for header search information.
HEADER_SEARCH_TABLE = 34,
- /// \brief Record code for floating point \#pragma options.
+ /// Record code for floating point \#pragma options.
FP_PRAGMA_OPTIONS = 35,
- /// \brief Record code for enabled OpenCL extensions.
+ /// Record code for enabled OpenCL extensions.
OPENCL_EXTENSIONS = 36,
- /// \brief The list of delegating constructor declarations.
+ /// The list of delegating constructor declarations.
DELEGATING_CTORS = 37,
- /// \brief Record code for the set of known namespaces, which are used
+ /// Record code for the set of known namespaces, which are used
/// for typo correction.
KNOWN_NAMESPACES = 38,
- /// \brief Record code for the remapping information used to relate
+ /// Record code for the remapping information used to relate
/// loaded modules to the various offsets and IDs(e.g., source location
/// offests, declaration and type IDs) that are used in that module to
/// refer to other modules.
MODULE_OFFSET_MAP = 39,
- /// \brief Record code for the source manager line table information,
+ /// Record code for the source manager line table information,
/// which stores information about \#line directives.
SOURCE_MANAGER_LINE_TABLE = 40,
- /// \brief Record code for map of Objective-C class definition IDs to the
+ /// Record code for map of Objective-C class definition IDs to the
/// ObjC categories in a module that are attached to that class.
OBJC_CATEGORIES_MAP = 41,
- /// \brief Record code for a file sorted array of DeclIDs in a module.
+ /// Record code for a file sorted array of DeclIDs in a module.
FILE_SORTED_DECLS = 42,
- /// \brief Record code for an array of all of the (sub)modules that were
+ /// Record code for an array of all of the (sub)modules that were
/// imported by the AST file.
IMPORTED_MODULES = 43,
// ID 44 used to be a table of merged canonical declarations.
// ID 45 used to be a list of declaration IDs of local redeclarations.
- /// \brief Record code for the array of Objective-C categories (including
+ /// Record code for the array of Objective-C categories (including
/// extensions).
///
/// This array can only be interpreted properly using the Objective-C
/// categories map.
OBJC_CATEGORIES = 46,
- /// \brief Record code for the table of offsets of each macro ID.
+ /// Record code for the table of offsets of each macro ID.
///
/// The offset table contains offsets into the blob stored in
/// the preprocessor block. Each offset points to the corresponding
/// macro definition.
MACRO_OFFSET = 47,
- /// \brief A list of "interesting" identifiers. Only used in C++ (where we
+ /// A list of "interesting" identifiers. Only used in C++ (where we
/// don't normally do lookups into the serialized identifier table). These
/// are eagerly deserialized.
INTERESTING_IDENTIFIERS = 48,
- /// \brief Record code for undefined but used functions and variables that
+ /// Record code for undefined but used functions and variables that
/// need a definition in this TU.
UNDEFINED_BUT_USED = 49,
- /// \brief Record code for late parsed template functions.
+ /// Record code for late parsed template functions.
LATE_PARSED_TEMPLATE = 50,
- /// \brief Record code for \#pragma optimize options.
+ /// Record code for \#pragma optimize options.
OPTIMIZE_PRAGMA_OPTIONS = 51,
- /// \brief Record code for potentially unused local typedef names.
+ /// Record code for potentially unused local typedef names.
UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES = 52,
// ID 53 used to be a table of constructor initializer records.
- /// \brief Delete expressions that will be analyzed later.
+ /// Delete expressions that will be analyzed later.
DELETE_EXPRS_TO_ANALYZE = 54,
- /// \brief Record code for \#pragma ms_struct options.
+ /// Record code for \#pragma ms_struct options.
MSSTRUCT_PRAGMA_OPTIONS = 55,
- /// \brief Record code for \#pragma ms_struct options.
+ /// Record code for \#pragma ms_struct options.
POINTERS_TO_MEMBERS_PRAGMA_OPTIONS = 56,
- /// \brief Number of unmatched #pragma clang cuda_force_host_device begin
+ /// Number of unmatched #pragma clang cuda_force_host_device begin
/// directives we've seen.
CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH = 57,
- /// \brief Record code for types associated with OpenCL extensions.
+ /// Record code for types associated with OpenCL extensions.
OPENCL_EXTENSION_TYPES = 58,
- /// \brief Record code for declarations associated with OpenCL extensions.
+ /// Record code for declarations associated with OpenCL extensions.
OPENCL_EXTENSION_DECLS = 59,
MODULAR_CODEGEN_DECLS = 60,
- /// \brief Record code for \#pragma pack options.
+ /// Record code for \#pragma pack options.
PACK_PRAGMA_OPTIONS = 61,
- /// \brief The stack of open #ifs/#ifdefs recorded in a preamble.
+ /// The stack of open #ifs/#ifdefs recorded in a preamble.
PP_CONDITIONAL_STACK = 62,
+
+ /// A table of skipped ranges within the preprocessing record.
+ PPD_SKIPPED_RANGES = 63
};
- /// \brief Record types used within a source manager block.
+ /// Record types used within a source manager block.
enum SourceManagerRecordTypes {
- /// \brief Describes a source location entry (SLocEntry) for a
+ /// Describes a source location entry (SLocEntry) for a
/// file.
SM_SLOC_FILE_ENTRY = 1,
- /// \brief Describes a source location entry (SLocEntry) for a
+ /// Describes a source location entry (SLocEntry) for a
/// buffer.
SM_SLOC_BUFFER_ENTRY = 2,
- /// \brief Describes a blob that contains the data for a buffer
+ /// Describes a blob that contains the data for a buffer
/// entry. This kind of record always directly follows a
/// SM_SLOC_BUFFER_ENTRY record or a SM_SLOC_FILE_ENTRY with an
/// overridden buffer.
SM_SLOC_BUFFER_BLOB = 3,
- /// \brief Describes a zlib-compressed blob that contains the data for
+ /// Describes a zlib-compressed blob that contains the data for
/// a buffer entry.
SM_SLOC_BUFFER_BLOB_COMPRESSED = 4,
- /// \brief Describes a source location entry (SLocEntry) for a
+ /// Describes a source location entry (SLocEntry) for a
/// macro expansion.
SM_SLOC_EXPANSION_ENTRY = 5
};
- /// \brief Record types used within a preprocessor block.
+ /// Record types used within a preprocessor block.
enum PreprocessorRecordTypes {
// The macros in the PP section are a PP_MACRO_* instance followed by a
// list of PP_TOKEN instances for each token in the definition.
- /// \brief An object-like macro definition.
+ /// An object-like macro definition.
/// [PP_MACRO_OBJECT_LIKE, IdentInfoID, SLoc, IsUsed]
PP_MACRO_OBJECT_LIKE = 1,
- /// \brief A function-like macro definition.
+ /// A function-like macro definition.
/// [PP_MACRO_FUNCTION_LIKE, \<ObjectLikeStuff>, IsC99Varargs,
/// IsGNUVarars, NumArgs, ArgIdentInfoID* ]
PP_MACRO_FUNCTION_LIKE = 2,
- /// \brief Describes one token.
+ /// Describes one token.
/// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags]
PP_TOKEN = 3,
- /// \brief The macro directives history for a particular identifier.
+ /// The macro directives history for a particular identifier.
PP_MACRO_DIRECTIVE_HISTORY = 4,
- /// \brief A macro directive exported by a module.
+ /// A macro directive exported by a module.
/// [PP_MODULE_MACRO, SubmoduleID, MacroID, (Overridden SubmoduleID)*]
PP_MODULE_MACRO = 5,
};
- /// \brief Record types used within a preprocessor detail block.
+ /// Record types used within a preprocessor detail block.
enum PreprocessorDetailRecordTypes {
- /// \brief Describes a macro expansion within the preprocessing record.
+ /// Describes a macro expansion within the preprocessing record.
PPD_MACRO_EXPANSION = 0,
- /// \brief Describes a macro definition within the preprocessing record.
+ /// Describes a macro definition within the preprocessing record.
PPD_MACRO_DEFINITION = 1,
- /// \brief Describes an inclusion directive within the preprocessing
+ /// Describes an inclusion directive within the preprocessing
/// record.
PPD_INCLUSION_DIRECTIVE = 2
};
- /// \brief Record types used within a submodule description block.
+ /// Record types used within a submodule description block.
enum SubmoduleRecordTypes {
- /// \brief Metadata for submodules as a whole.
+ /// Metadata for submodules as a whole.
SUBMODULE_METADATA = 0,
- /// \brief Defines the major attributes of a submodule, including its
+ /// Defines the major attributes of a submodule, including its
/// name and parent.
SUBMODULE_DEFINITION = 1,
- /// \brief Specifies the umbrella header used to create this module,
+ /// Specifies the umbrella header used to create this module,
/// if any.
SUBMODULE_UMBRELLA_HEADER = 2,
- /// \brief Specifies a header that falls into this (sub)module.
+ /// Specifies a header that falls into this (sub)module.
SUBMODULE_HEADER = 3,
- /// \brief Specifies a top-level header that falls into this (sub)module.
+ /// Specifies a top-level header that falls into this (sub)module.
SUBMODULE_TOPHEADER = 4,
- /// \brief Specifies an umbrella directory.
+ /// Specifies an umbrella directory.
SUBMODULE_UMBRELLA_DIR = 5,
- /// \brief Specifies the submodules that are imported by this
+ /// Specifies the submodules that are imported by this
/// submodule.
SUBMODULE_IMPORTS = 6,
- /// \brief Specifies the submodules that are re-exported from this
+ /// Specifies the submodules that are re-exported from this
/// submodule.
SUBMODULE_EXPORTS = 7,
- /// \brief Specifies a required feature.
+ /// Specifies a required feature.
SUBMODULE_REQUIRES = 8,
- /// \brief Specifies a header that has been explicitly excluded
+ /// Specifies a header that has been explicitly excluded
/// from this submodule.
SUBMODULE_EXCLUDED_HEADER = 9,
- /// \brief Specifies a library or framework to link against.
+ /// Specifies a library or framework to link against.
SUBMODULE_LINK_LIBRARY = 10,
- /// \brief Specifies a configuration macro for this module.
+ /// Specifies a configuration macro for this module.
SUBMODULE_CONFIG_MACRO = 11,
- /// \brief Specifies a conflict with another module.
+ /// Specifies a conflict with another module.
SUBMODULE_CONFLICT = 12,
- /// \brief Specifies a header that is private to this submodule.
+ /// Specifies a header that is private to this submodule.
SUBMODULE_PRIVATE_HEADER = 13,
- /// \brief Specifies a header that is part of the module but must be
+ /// Specifies a header that is part of the module but must be
/// textually included.
SUBMODULE_TEXTUAL_HEADER = 14,
- /// \brief Specifies a header that is private to this submodule but
+ /// Specifies a header that is private to this submodule but
/// must be textually included.
SUBMODULE_PRIVATE_TEXTUAL_HEADER = 15,
- /// \brief Specifies some declarations with initializers that must be
+ /// Specifies some declarations with initializers that must be
/// emitted to initialize the module.
SUBMODULE_INITIALIZERS = 16,
- /// \brief Specifies the name of the module that will eventually
+ /// Specifies the name of the module that will eventually
/// re-export the entities in this module.
SUBMODULE_EXPORT_AS = 17,
};
- /// \brief Record types used within a comments block.
+ /// Record types used within a comments block.
enum CommentRecordTypes {
COMMENTS_RAW_COMMENT = 0
};
@@ -771,7 +793,7 @@ namespace serialization {
///
/// @{
- /// \brief Predefined type IDs.
+ /// Predefined type IDs.
///
/// These type IDs correspond to predefined types in the AST
/// context, such as built-in types (int) and special place-holder
@@ -779,496 +801,574 @@ namespace serialization {
/// types are never actually serialized, since they will be built
/// by the AST context when it is created.
enum PredefinedTypeIDs {
- /// \brief The NULL type.
+ /// The NULL type.
PREDEF_TYPE_NULL_ID = 0,
- /// \brief The void type.
+ /// The void type.
PREDEF_TYPE_VOID_ID = 1,
- /// \brief The 'bool' or '_Bool' type.
+ /// The 'bool' or '_Bool' type.
PREDEF_TYPE_BOOL_ID = 2,
- /// \brief The 'char' type, when it is unsigned.
+ /// The 'char' type, when it is unsigned.
PREDEF_TYPE_CHAR_U_ID = 3,
- /// \brief The 'unsigned char' type.
+ /// The 'unsigned char' type.
PREDEF_TYPE_UCHAR_ID = 4,
- /// \brief The 'unsigned short' type.
+ /// The 'unsigned short' type.
PREDEF_TYPE_USHORT_ID = 5,
- /// \brief The 'unsigned int' type.
+ /// The 'unsigned int' type.
PREDEF_TYPE_UINT_ID = 6,
- /// \brief The 'unsigned long' type.
+ /// The 'unsigned long' type.
PREDEF_TYPE_ULONG_ID = 7,
- /// \brief The 'unsigned long long' type.
+ /// The 'unsigned long long' type.
PREDEF_TYPE_ULONGLONG_ID = 8,
- /// \brief The 'char' type, when it is signed.
+ /// The 'char' type, when it is signed.
PREDEF_TYPE_CHAR_S_ID = 9,
- /// \brief The 'signed char' type.
+ /// The 'signed char' type.
PREDEF_TYPE_SCHAR_ID = 10,
- /// \brief The C++ 'wchar_t' type.
+ /// The C++ 'wchar_t' type.
PREDEF_TYPE_WCHAR_ID = 11,
- /// \brief The (signed) 'short' type.
+ /// The (signed) 'short' type.
PREDEF_TYPE_SHORT_ID = 12,
- /// \brief The (signed) 'int' type.
+ /// The (signed) 'int' type.
PREDEF_TYPE_INT_ID = 13,
- /// \brief The (signed) 'long' type.
+ /// The (signed) 'long' type.
PREDEF_TYPE_LONG_ID = 14,
- /// \brief The (signed) 'long long' type.
+ /// The (signed) 'long long' type.
PREDEF_TYPE_LONGLONG_ID = 15,
- /// \brief The 'float' type.
+ /// The 'float' type.
PREDEF_TYPE_FLOAT_ID = 16,
- /// \brief The 'double' type.
+ /// The 'double' type.
PREDEF_TYPE_DOUBLE_ID = 17,
- /// \brief The 'long double' type.
+ /// The 'long double' type.
PREDEF_TYPE_LONGDOUBLE_ID = 18,
- /// \brief The placeholder type for overloaded function sets.
+ /// The placeholder type for overloaded function sets.
PREDEF_TYPE_OVERLOAD_ID = 19,
- /// \brief The placeholder type for dependent types.
+ /// The placeholder type for dependent types.
PREDEF_TYPE_DEPENDENT_ID = 20,
- /// \brief The '__uint128_t' type.
+ /// The '__uint128_t' type.
PREDEF_TYPE_UINT128_ID = 21,
- /// \brief The '__int128_t' type.
+ /// The '__int128_t' type.
PREDEF_TYPE_INT128_ID = 22,
- /// \brief The type of 'nullptr'.
+ /// The type of 'nullptr'.
PREDEF_TYPE_NULLPTR_ID = 23,
- /// \brief The C++ 'char16_t' type.
+ /// The C++ 'char16_t' type.
PREDEF_TYPE_CHAR16_ID = 24,
- /// \brief The C++ 'char32_t' type.
+ /// The C++ 'char32_t' type.
PREDEF_TYPE_CHAR32_ID = 25,
- /// \brief The ObjC 'id' type.
+ /// The ObjC 'id' type.
PREDEF_TYPE_OBJC_ID = 26,
- /// \brief The ObjC 'Class' type.
+ /// The ObjC 'Class' type.
PREDEF_TYPE_OBJC_CLASS = 27,
- /// \brief The ObjC 'SEL' type.
+ /// The ObjC 'SEL' type.
PREDEF_TYPE_OBJC_SEL = 28,
- /// \brief The 'unknown any' placeholder type.
+ /// The 'unknown any' placeholder type.
PREDEF_TYPE_UNKNOWN_ANY = 29,
- /// \brief The placeholder type for bound member functions.
+ /// The placeholder type for bound member functions.
PREDEF_TYPE_BOUND_MEMBER = 30,
- /// \brief The "auto" deduction type.
+ /// The "auto" deduction type.
PREDEF_TYPE_AUTO_DEDUCT = 31,
- /// \brief The "auto &&" deduction type.
+ /// The "auto &&" deduction type.
PREDEF_TYPE_AUTO_RREF_DEDUCT = 32,
- /// \brief The OpenCL 'half' / ARM NEON __fp16 type.
+ /// The OpenCL 'half' / ARM NEON __fp16 type.
PREDEF_TYPE_HALF_ID = 33,
- /// \brief ARC's unbridged-cast placeholder type.
+ /// ARC's unbridged-cast placeholder type.
PREDEF_TYPE_ARC_UNBRIDGED_CAST = 34,
- /// \brief The pseudo-object placeholder type.
+ /// The pseudo-object placeholder type.
PREDEF_TYPE_PSEUDO_OBJECT = 35,
- /// \brief The placeholder type for builtin functions.
+ /// The placeholder type for builtin functions.
PREDEF_TYPE_BUILTIN_FN = 36,
- /// \brief OpenCL event type.
+ /// OpenCL event type.
PREDEF_TYPE_EVENT_ID = 37,
- /// \brief OpenCL clk event type.
+ /// OpenCL clk event type.
PREDEF_TYPE_CLK_EVENT_ID = 38,
- /// \brief OpenCL sampler type.
+ /// OpenCL sampler type.
PREDEF_TYPE_SAMPLER_ID = 39,
- /// \brief OpenCL queue type.
+ /// OpenCL queue type.
PREDEF_TYPE_QUEUE_ID = 40,
- /// \brief OpenCL reserve_id type.
+ /// OpenCL reserve_id type.
PREDEF_TYPE_RESERVE_ID_ID = 41,
- /// \brief The placeholder type for OpenMP array section.
+ /// The placeholder type for OpenMP array section.
PREDEF_TYPE_OMP_ARRAY_SECTION = 42,
- /// \brief The '__float128' type
+ /// The '__float128' type
PREDEF_TYPE_FLOAT128_ID = 43,
- /// \brief The '_Float16' type
+ /// The '_Float16' type
PREDEF_TYPE_FLOAT16_ID = 44,
- /// \brief OpenCL image types with auto numeration
+ /// The C++ 'char8_t' type.
+ PREDEF_TYPE_CHAR8_ID = 45,
+
+ /// \brief The 'short _Accum' type
+ PREDEF_TYPE_SHORT_ACCUM_ID = 46,
+
+ /// \brief The '_Accum' type
+ PREDEF_TYPE_ACCUM_ID = 47,
+
+ /// \brief The 'long _Accum' type
+ PREDEF_TYPE_LONG_ACCUM_ID = 48,
+
+ /// \brief The 'unsigned short _Accum' type
+ PREDEF_TYPE_USHORT_ACCUM_ID = 49,
+
+ /// \brief The 'unsigned _Accum' type
+ PREDEF_TYPE_UACCUM_ID = 50,
+
+ /// \brief The 'unsigned long _Accum' type
+ PREDEF_TYPE_ULONG_ACCUM_ID = 51,
+
+ /// \brief The 'short _Fract' type
+ PREDEF_TYPE_SHORT_FRACT_ID = 52,
+
+ /// \brief The '_Fract' type
+ PREDEF_TYPE_FRACT_ID = 53,
+
+ /// \brief The 'long _Fract' type
+ PREDEF_TYPE_LONG_FRACT_ID = 54,
+
+ /// \brief The 'unsigned short _Fract' type
+ PREDEF_TYPE_USHORT_FRACT_ID = 55,
+
+ /// \brief The 'unsigned _Fract' type
+ PREDEF_TYPE_UFRACT_ID = 56,
+
+ /// \brief The 'unsigned long _Fract' type
+ PREDEF_TYPE_ULONG_FRACT_ID = 57,
+
+ /// \brief The '_Sat short _Accum' type
+ PREDEF_TYPE_SAT_SHORT_ACCUM_ID = 58,
+
+ /// \brief The '_Sat _Accum' type
+ PREDEF_TYPE_SAT_ACCUM_ID = 59,
+
+ /// \brief The '_Sat long _Accum' type
+ PREDEF_TYPE_SAT_LONG_ACCUM_ID = 60,
+
+ /// \brief The '_Sat unsigned short _Accum' type
+ PREDEF_TYPE_SAT_USHORT_ACCUM_ID = 61,
+
+ /// \brief The '_Sat unsigned _Accum' type
+ PREDEF_TYPE_SAT_UACCUM_ID = 62,
+
+ /// \brief The '_Sat unsigned long _Accum' type
+ PREDEF_TYPE_SAT_ULONG_ACCUM_ID = 63,
+
+ /// \brief The '_Sat short _Fract' type
+ PREDEF_TYPE_SAT_SHORT_FRACT_ID = 64,
+
+ /// \brief The '_Sat _Fract' type
+ PREDEF_TYPE_SAT_FRACT_ID = 65,
+
+ /// \brief The '_Sat long _Fract' type
+ PREDEF_TYPE_SAT_LONG_FRACT_ID = 66,
+
+ /// \brief The '_Sat unsigned short _Fract' type
+ PREDEF_TYPE_SAT_USHORT_FRACT_ID = 67,
+
+ /// \brief The '_Sat unsigned _Fract' type
+ PREDEF_TYPE_SAT_UFRACT_ID = 68,
+
+ /// \brief The '_Sat unsigned long _Fract' type
+ PREDEF_TYPE_SAT_ULONG_FRACT_ID = 69,
+
+ /// OpenCL image types with auto numeration
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
PREDEF_TYPE_##Id##_ID,
#include "clang/Basic/OpenCLImageTypes.def"
};
- /// \brief The number of predefined type IDs that are reserved for
+ /// The number of predefined type IDs that are reserved for
/// the PREDEF_TYPE_* constants.
///
/// Type IDs for non-predefined types will start at
/// NUM_PREDEF_TYPE_IDs.
- const unsigned NUM_PREDEF_TYPE_IDS = 100;
+ const unsigned NUM_PREDEF_TYPE_IDS = 200;
- /// \brief Record codes for each kind of type.
+ /// Record codes for each kind of type.
///
/// These constants describe the type records that can occur within a
/// block identified by DECLTYPES_BLOCK_ID in the AST file. Each
/// constant describes a record for a specific type class in the
/// AST. Note that DeclCode values share this code space.
enum TypeCode {
- /// \brief An ExtQualType record.
- TYPE_EXT_QUAL = 1,
+ /// An ExtQualType record.
+ TYPE_EXT_QUAL = 1,
- /// \brief A ComplexType record.
- TYPE_COMPLEX = 3,
+ /// A ComplexType record.
+ TYPE_COMPLEX = 3,
- /// \brief A PointerType record.
- TYPE_POINTER = 4,
+ /// A PointerType record.
+ TYPE_POINTER = 4,
- /// \brief A BlockPointerType record.
- TYPE_BLOCK_POINTER = 5,
+ /// A BlockPointerType record.
+ TYPE_BLOCK_POINTER = 5,
- /// \brief An LValueReferenceType record.
- TYPE_LVALUE_REFERENCE = 6,
+ /// An LValueReferenceType record.
+ TYPE_LVALUE_REFERENCE = 6,
- /// \brief An RValueReferenceType record.
- TYPE_RVALUE_REFERENCE = 7,
+ /// An RValueReferenceType record.
+ TYPE_RVALUE_REFERENCE = 7,
- /// \brief A MemberPointerType record.
- TYPE_MEMBER_POINTER = 8,
+ /// A MemberPointerType record.
+ TYPE_MEMBER_POINTER = 8,
- /// \brief A ConstantArrayType record.
- TYPE_CONSTANT_ARRAY = 9,
+ /// A ConstantArrayType record.
+ TYPE_CONSTANT_ARRAY = 9,
- /// \brief An IncompleteArrayType record.
- TYPE_INCOMPLETE_ARRAY = 10,
+ /// An IncompleteArrayType record.
+ TYPE_INCOMPLETE_ARRAY = 10,
- /// \brief A VariableArrayType record.
- TYPE_VARIABLE_ARRAY = 11,
+ /// A VariableArrayType record.
+ TYPE_VARIABLE_ARRAY = 11,
- /// \brief A VectorType record.
- TYPE_VECTOR = 12,
+ /// A VectorType record.
+ TYPE_VECTOR = 12,
- /// \brief An ExtVectorType record.
- TYPE_EXT_VECTOR = 13,
+ /// An ExtVectorType record.
+ TYPE_EXT_VECTOR = 13,
- /// \brief A FunctionNoProtoType record.
- TYPE_FUNCTION_NO_PROTO = 14,
+ /// A FunctionNoProtoType record.
+ TYPE_FUNCTION_NO_PROTO = 14,
- /// \brief A FunctionProtoType record.
- TYPE_FUNCTION_PROTO = 15,
+ /// A FunctionProtoType record.
+ TYPE_FUNCTION_PROTO = 15,
- /// \brief A TypedefType record.
- TYPE_TYPEDEF = 16,
+ /// A TypedefType record.
+ TYPE_TYPEDEF = 16,
- /// \brief A TypeOfExprType record.
- TYPE_TYPEOF_EXPR = 17,
+ /// A TypeOfExprType record.
+ TYPE_TYPEOF_EXPR = 17,
- /// \brief A TypeOfType record.
- TYPE_TYPEOF = 18,
+ /// A TypeOfType record.
+ TYPE_TYPEOF = 18,
- /// \brief A RecordType record.
- TYPE_RECORD = 19,
+ /// A RecordType record.
+ TYPE_RECORD = 19,
- /// \brief An EnumType record.
- TYPE_ENUM = 20,
+ /// An EnumType record.
+ TYPE_ENUM = 20,
- /// \brief An ObjCInterfaceType record.
- TYPE_OBJC_INTERFACE = 21,
+ /// An ObjCInterfaceType record.
+ TYPE_OBJC_INTERFACE = 21,
- /// \brief An ObjCObjectPointerType record.
- TYPE_OBJC_OBJECT_POINTER = 22,
+ /// An ObjCObjectPointerType record.
+ TYPE_OBJC_OBJECT_POINTER = 22,
- /// \brief a DecltypeType record.
- TYPE_DECLTYPE = 23,
+ /// a DecltypeType record.
+ TYPE_DECLTYPE = 23,
- /// \brief An ElaboratedType record.
- TYPE_ELABORATED = 24,
+ /// An ElaboratedType record.
+ TYPE_ELABORATED = 24,
- /// \brief A SubstTemplateTypeParmType record.
+ /// A SubstTemplateTypeParmType record.
TYPE_SUBST_TEMPLATE_TYPE_PARM = 25,
- /// \brief An UnresolvedUsingType record.
- TYPE_UNRESOLVED_USING = 26,
+ /// An UnresolvedUsingType record.
+ TYPE_UNRESOLVED_USING = 26,
- /// \brief An InjectedClassNameType record.
- TYPE_INJECTED_CLASS_NAME = 27,
+ /// An InjectedClassNameType record.
+ TYPE_INJECTED_CLASS_NAME = 27,
- /// \brief An ObjCObjectType record.
- TYPE_OBJC_OBJECT = 28,
+ /// An ObjCObjectType record.
+ TYPE_OBJC_OBJECT = 28,
- /// \brief An TemplateTypeParmType record.
- TYPE_TEMPLATE_TYPE_PARM = 29,
+ /// An TemplateTypeParmType record.
+ TYPE_TEMPLATE_TYPE_PARM = 29,
- /// \brief An TemplateSpecializationType record.
- TYPE_TEMPLATE_SPECIALIZATION = 30,
+ /// An TemplateSpecializationType record.
+ TYPE_TEMPLATE_SPECIALIZATION = 30,
- /// \brief A DependentNameType record.
- TYPE_DEPENDENT_NAME = 31,
+ /// A DependentNameType record.
+ TYPE_DEPENDENT_NAME = 31,
- /// \brief A DependentTemplateSpecializationType record.
+ /// A DependentTemplateSpecializationType record.
TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32,
- /// \brief A DependentSizedArrayType record.
- TYPE_DEPENDENT_SIZED_ARRAY = 33,
+ /// A DependentSizedArrayType record.
+ TYPE_DEPENDENT_SIZED_ARRAY = 33,
- /// \brief A ParenType record.
- TYPE_PAREN = 34,
+ /// A ParenType record.
+ TYPE_PAREN = 34,
- /// \brief A PackExpansionType record.
- TYPE_PACK_EXPANSION = 35,
+ /// A PackExpansionType record.
+ TYPE_PACK_EXPANSION = 35,
- /// \brief An AttributedType record.
- TYPE_ATTRIBUTED = 36,
+ /// An AttributedType record.
+ TYPE_ATTRIBUTED = 36,
- /// \brief A SubstTemplateTypeParmPackType record.
+ /// A SubstTemplateTypeParmPackType record.
TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37,
- /// \brief A AutoType record.
- TYPE_AUTO = 38,
+ /// A AutoType record.
+ TYPE_AUTO = 38,
- /// \brief A UnaryTransformType record.
- TYPE_UNARY_TRANSFORM = 39,
+ /// A UnaryTransformType record.
+ TYPE_UNARY_TRANSFORM = 39,
- /// \brief An AtomicType record.
- TYPE_ATOMIC = 40,
+ /// An AtomicType record.
+ TYPE_ATOMIC = 40,
- /// \brief A DecayedType record.
- TYPE_DECAYED = 41,
+ /// A DecayedType record.
+ TYPE_DECAYED = 41,
- /// \brief An AdjustedType record.
- TYPE_ADJUSTED = 42,
+ /// An AdjustedType record.
+ TYPE_ADJUSTED = 42,
- /// \brief A PipeType record.
- TYPE_PIPE = 43,
+ /// A PipeType record.
+ TYPE_PIPE = 43,
- /// \brief An ObjCTypeParamType record.
- TYPE_OBJC_TYPE_PARAM = 44,
+ /// An ObjCTypeParamType record.
+ TYPE_OBJC_TYPE_PARAM = 44,
- /// \brief A DeducedTemplateSpecializationType record.
+ /// A DeducedTemplateSpecializationType record.
TYPE_DEDUCED_TEMPLATE_SPECIALIZATION = 45,
- /// \brief A DependentSizedExtVectorType record.
+ /// A DependentSizedExtVectorType record.
TYPE_DEPENDENT_SIZED_EXT_VECTOR = 46,
- /// \brief A DependentAddressSpaceType record.
- TYPE_DEPENDENT_ADDRESS_SPACE = 47
+ /// A DependentAddressSpaceType record.
+ TYPE_DEPENDENT_ADDRESS_SPACE = 47,
+
+ /// A dependentSizedVectorType record.
+ TYPE_DEPENDENT_SIZED_VECTOR = 48
};
- /// \brief The type IDs for special types constructed by semantic
+ /// The type IDs for special types constructed by semantic
/// analysis.
///
/// The constants in this enumeration are indices into the
/// SPECIAL_TYPES record.
enum SpecialTypeIDs {
- /// \brief CFConstantString type
+ /// CFConstantString type
SPECIAL_TYPE_CF_CONSTANT_STRING = 0,
- /// \brief C FILE typedef type
+ /// C FILE typedef type
SPECIAL_TYPE_FILE = 1,
- /// \brief C jmp_buf typedef type
+ /// C jmp_buf typedef type
SPECIAL_TYPE_JMP_BUF = 2,
- /// \brief C sigjmp_buf typedef type
+ /// C sigjmp_buf typedef type
SPECIAL_TYPE_SIGJMP_BUF = 3,
- /// \brief Objective-C "id" redefinition type
+ /// Objective-C "id" redefinition type
SPECIAL_TYPE_OBJC_ID_REDEFINITION = 4,
- /// \brief Objective-C "Class" redefinition type
+ /// Objective-C "Class" redefinition type
SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 5,
- /// \brief Objective-C "SEL" redefinition type
+ /// Objective-C "SEL" redefinition type
SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 6,
- /// \brief C ucontext_t typedef type
+ /// C ucontext_t typedef type
SPECIAL_TYPE_UCONTEXT_T = 7
};
- /// \brief The number of special type IDs.
+ /// The number of special type IDs.
const unsigned NumSpecialTypeIDs = 8;
- /// \brief Predefined declaration IDs.
+ /// Predefined declaration IDs.
///
/// These declaration IDs correspond to predefined declarations in the AST
/// context, such as the NULL declaration ID. Such declarations are never
/// actually serialized, since they will be built by the AST context when
/// it is created.
enum PredefinedDeclIDs {
- /// \brief The NULL declaration.
+ /// The NULL declaration.
PREDEF_DECL_NULL_ID = 0,
- /// \brief The translation unit.
+ /// The translation unit.
PREDEF_DECL_TRANSLATION_UNIT_ID = 1,
- /// \brief The Objective-C 'id' type.
+ /// The Objective-C 'id' type.
PREDEF_DECL_OBJC_ID_ID = 2,
- /// \brief The Objective-C 'SEL' type.
+ /// The Objective-C 'SEL' type.
PREDEF_DECL_OBJC_SEL_ID = 3,
- /// \brief The Objective-C 'Class' type.
+ /// The Objective-C 'Class' type.
PREDEF_DECL_OBJC_CLASS_ID = 4,
- /// \brief The Objective-C 'Protocol' type.
+ /// The Objective-C 'Protocol' type.
PREDEF_DECL_OBJC_PROTOCOL_ID = 5,
- /// \brief The signed 128-bit integer type.
+ /// The signed 128-bit integer type.
PREDEF_DECL_INT_128_ID = 6,
- /// \brief The unsigned 128-bit integer type.
+ /// The unsigned 128-bit integer type.
PREDEF_DECL_UNSIGNED_INT_128_ID = 7,
- /// \brief The internal 'instancetype' typedef.
+ /// The internal 'instancetype' typedef.
PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8,
- /// \brief The internal '__builtin_va_list' typedef.
+ /// The internal '__builtin_va_list' typedef.
PREDEF_DECL_BUILTIN_VA_LIST_ID = 9,
- /// \brief The internal '__va_list_tag' struct, if any.
+ /// The internal '__va_list_tag' struct, if any.
PREDEF_DECL_VA_LIST_TAG = 10,
- /// \brief The internal '__builtin_ms_va_list' typedef.
+ /// The internal '__builtin_ms_va_list' typedef.
PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11,
- /// \brief The extern "C" context.
+ /// The extern "C" context.
PREDEF_DECL_EXTERN_C_CONTEXT_ID = 12,
- /// \brief The internal '__make_integer_seq' template.
+ /// The internal '__make_integer_seq' template.
PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 13,
- /// \brief The internal '__NSConstantString' typedef.
+ /// The internal '__NSConstantString' typedef.
PREDEF_DECL_CF_CONSTANT_STRING_ID = 14,
- /// \brief The internal '__NSConstantString' tag type.
+ /// The internal '__NSConstantString' tag type.
PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 15,
- /// \brief The internal '__type_pack_element' template.
+ /// The internal '__type_pack_element' template.
PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 16,
};
- /// \brief The number of declaration IDs that are predefined.
+ /// The number of declaration IDs that are predefined.
///
/// For more information about predefined declarations, see the
/// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants.
const unsigned int NUM_PREDEF_DECL_IDS = 17;
- /// \brief Record of updates for a declaration that was modified after
+ /// Record of updates for a declaration that was modified after
/// being deserialized. This can occur within DECLTYPES_BLOCK_ID.
const unsigned int DECL_UPDATES = 49;
- /// \brief Record code for a list of local redeclarations of a declaration.
+ /// Record code for a list of local redeclarations of a declaration.
/// This can occur within DECLTYPES_BLOCK_ID.
const unsigned int LOCAL_REDECLARATIONS = 50;
- /// \brief Record codes for each kind of declaration.
+ /// Record codes for each kind of declaration.
///
/// These constants describe the declaration records that can occur within
/// a declarations block (identified by DECLTYPES_BLOCK_ID). Each
/// constant describes a record for a specific declaration class
/// in the AST. Note that TypeCode values share this code space.
enum DeclCode {
- /// \brief A TypedefDecl record.
+ /// A TypedefDecl record.
DECL_TYPEDEF = 51,
- /// \brief A TypeAliasDecl record.
+ /// A TypeAliasDecl record.
DECL_TYPEALIAS,
- /// \brief An EnumDecl record.
+ /// An EnumDecl record.
DECL_ENUM,
- /// \brief A RecordDecl record.
+ /// A RecordDecl record.
DECL_RECORD,
- /// \brief An EnumConstantDecl record.
+ /// An EnumConstantDecl record.
DECL_ENUM_CONSTANT,
- /// \brief A FunctionDecl record.
+ /// A FunctionDecl record.
DECL_FUNCTION,
- /// \brief A ObjCMethodDecl record.
+ /// A ObjCMethodDecl record.
DECL_OBJC_METHOD,
- /// \brief A ObjCInterfaceDecl record.
+ /// A ObjCInterfaceDecl record.
DECL_OBJC_INTERFACE,
- /// \brief A ObjCProtocolDecl record.
+ /// A ObjCProtocolDecl record.
DECL_OBJC_PROTOCOL,
- /// \brief A ObjCIvarDecl record.
+ /// A ObjCIvarDecl record.
DECL_OBJC_IVAR,
- /// \brief A ObjCAtDefsFieldDecl record.
+ /// A ObjCAtDefsFieldDecl record.
DECL_OBJC_AT_DEFS_FIELD,
- /// \brief A ObjCCategoryDecl record.
+ /// A ObjCCategoryDecl record.
DECL_OBJC_CATEGORY,
- /// \brief A ObjCCategoryImplDecl record.
+ /// A ObjCCategoryImplDecl record.
DECL_OBJC_CATEGORY_IMPL,
- /// \brief A ObjCImplementationDecl record.
+ /// A ObjCImplementationDecl record.
DECL_OBJC_IMPLEMENTATION,
- /// \brief A ObjCCompatibleAliasDecl record.
+ /// A ObjCCompatibleAliasDecl record.
DECL_OBJC_COMPATIBLE_ALIAS,
- /// \brief A ObjCPropertyDecl record.
+ /// A ObjCPropertyDecl record.
DECL_OBJC_PROPERTY,
- /// \brief A ObjCPropertyImplDecl record.
+ /// A ObjCPropertyImplDecl record.
DECL_OBJC_PROPERTY_IMPL,
- /// \brief A FieldDecl record.
+ /// A FieldDecl record.
DECL_FIELD,
- /// \brief A MSPropertyDecl record.
+ /// A MSPropertyDecl record.
DECL_MS_PROPERTY,
- /// \brief A VarDecl record.
+ /// A VarDecl record.
DECL_VAR,
- /// \brief An ImplicitParamDecl record.
+ /// An ImplicitParamDecl record.
DECL_IMPLICIT_PARAM,
- /// \brief A ParmVarDecl record.
+ /// A ParmVarDecl record.
DECL_PARM_VAR,
- /// \brief A DecompositionDecl record.
+ /// A DecompositionDecl record.
DECL_DECOMPOSITION,
- /// \brief A BindingDecl record.
+ /// A BindingDecl record.
DECL_BINDING,
- /// \brief A FileScopeAsmDecl record.
+ /// A FileScopeAsmDecl record.
DECL_FILE_SCOPE_ASM,
- /// \brief A BlockDecl record.
+ /// A BlockDecl record.
DECL_BLOCK,
- /// \brief A CapturedDecl record.
+ /// A CapturedDecl record.
DECL_CAPTURED,
- /// \brief A record that stores the set of declarations that are
+ /// A record that stores the set of declarations that are
/// lexically stored within a given DeclContext.
///
/// The record itself is a blob that is an array of declaration IDs,
@@ -1278,7 +1378,7 @@ namespace serialization {
/// DeclContext::decls_begin() and DeclContext::decls_end().
DECL_CONTEXT_LEXICAL,
- /// \brief A record that stores the set of declarations that are
+ /// A record that stores the set of declarations that are
/// visible from a given DeclContext.
///
/// The record itself stores a set of mappings, each of which
@@ -1287,155 +1387,155 @@ namespace serialization {
/// into a DeclContext via DeclContext::lookup.
DECL_CONTEXT_VISIBLE,
- /// \brief A LabelDecl record.
+ /// A LabelDecl record.
DECL_LABEL,
- /// \brief A NamespaceDecl record.
+ /// A NamespaceDecl record.
DECL_NAMESPACE,
- /// \brief A NamespaceAliasDecl record.
+ /// A NamespaceAliasDecl record.
DECL_NAMESPACE_ALIAS,
- /// \brief A UsingDecl record.
+ /// A UsingDecl record.
DECL_USING,
- /// \brief A UsingPackDecl record.
+ /// A UsingPackDecl record.
DECL_USING_PACK,
- /// \brief A UsingShadowDecl record.
+ /// A UsingShadowDecl record.
DECL_USING_SHADOW,
- /// \brief A ConstructorUsingShadowDecl record.
+ /// A ConstructorUsingShadowDecl record.
DECL_CONSTRUCTOR_USING_SHADOW,
- /// \brief A UsingDirecitveDecl record.
+ /// A UsingDirecitveDecl record.
DECL_USING_DIRECTIVE,
- /// \brief An UnresolvedUsingValueDecl record.
+ /// An UnresolvedUsingValueDecl record.
DECL_UNRESOLVED_USING_VALUE,
- /// \brief An UnresolvedUsingTypenameDecl record.
+ /// An UnresolvedUsingTypenameDecl record.
DECL_UNRESOLVED_USING_TYPENAME,
- /// \brief A LinkageSpecDecl record.
+ /// A LinkageSpecDecl record.
DECL_LINKAGE_SPEC,
- /// \brief An ExportDecl record.
+ /// An ExportDecl record.
DECL_EXPORT,
- /// \brief A CXXRecordDecl record.
+ /// A CXXRecordDecl record.
DECL_CXX_RECORD,
- /// \brief A CXXDeductionGuideDecl record.
+ /// A CXXDeductionGuideDecl record.
DECL_CXX_DEDUCTION_GUIDE,
- /// \brief A CXXMethodDecl record.
+ /// A CXXMethodDecl record.
DECL_CXX_METHOD,
- /// \brief A CXXConstructorDecl record.
+ /// A CXXConstructorDecl record.
DECL_CXX_CONSTRUCTOR,
- /// \brief A CXXConstructorDecl record for an inherited constructor.
+ /// A CXXConstructorDecl record for an inherited constructor.
DECL_CXX_INHERITED_CONSTRUCTOR,
- /// \brief A CXXDestructorDecl record.
+ /// A CXXDestructorDecl record.
DECL_CXX_DESTRUCTOR,
- /// \brief A CXXConversionDecl record.
+ /// A CXXConversionDecl record.
DECL_CXX_CONVERSION,
- /// \brief An AccessSpecDecl record.
+ /// An AccessSpecDecl record.
DECL_ACCESS_SPEC,
- /// \brief A FriendDecl record.
+ /// A FriendDecl record.
DECL_FRIEND,
- /// \brief A FriendTemplateDecl record.
+ /// A FriendTemplateDecl record.
DECL_FRIEND_TEMPLATE,
- /// \brief A ClassTemplateDecl record.
+ /// A ClassTemplateDecl record.
DECL_CLASS_TEMPLATE,
- /// \brief A ClassTemplateSpecializationDecl record.
+ /// A ClassTemplateSpecializationDecl record.
DECL_CLASS_TEMPLATE_SPECIALIZATION,
- /// \brief A ClassTemplatePartialSpecializationDecl record.
+ /// A ClassTemplatePartialSpecializationDecl record.
DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
- /// \brief A VarTemplateDecl record.
+ /// A VarTemplateDecl record.
DECL_VAR_TEMPLATE,
- /// \brief A VarTemplateSpecializationDecl record.
+ /// A VarTemplateSpecializationDecl record.
DECL_VAR_TEMPLATE_SPECIALIZATION,
- /// \brief A VarTemplatePartialSpecializationDecl record.
+ /// A VarTemplatePartialSpecializationDecl record.
DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION,
- /// \brief A FunctionTemplateDecl record.
+ /// A FunctionTemplateDecl record.
DECL_FUNCTION_TEMPLATE,
- /// \brief A TemplateTypeParmDecl record.
+ /// A TemplateTypeParmDecl record.
DECL_TEMPLATE_TYPE_PARM,
- /// \brief A NonTypeTemplateParmDecl record.
+ /// A NonTypeTemplateParmDecl record.
DECL_NON_TYPE_TEMPLATE_PARM,
- /// \brief A TemplateTemplateParmDecl record.
+ /// A TemplateTemplateParmDecl record.
DECL_TEMPLATE_TEMPLATE_PARM,
- /// \brief A TypeAliasTemplateDecl record.
+ /// A TypeAliasTemplateDecl record.
DECL_TYPE_ALIAS_TEMPLATE,
- /// \brief A StaticAssertDecl record.
+ /// A StaticAssertDecl record.
DECL_STATIC_ASSERT,
- /// \brief A record containing CXXBaseSpecifiers.
+ /// A record containing CXXBaseSpecifiers.
DECL_CXX_BASE_SPECIFIERS,
- /// \brief A record containing CXXCtorInitializers.
+ /// A record containing CXXCtorInitializers.
DECL_CXX_CTOR_INITIALIZERS,
- /// \brief A IndirectFieldDecl record.
+ /// A IndirectFieldDecl record.
DECL_INDIRECTFIELD,
- /// \brief A NonTypeTemplateParmDecl record that stores an expanded
+ /// A NonTypeTemplateParmDecl record that stores an expanded
/// non-type template parameter pack.
DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK,
- /// \brief A TemplateTemplateParmDecl record that stores an expanded
+ /// A TemplateTemplateParmDecl record that stores an expanded
/// template template parameter pack.
DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK,
- /// \brief A ClassScopeFunctionSpecializationDecl record a class scope
+ /// A ClassScopeFunctionSpecializationDecl record a class scope
/// function specialization. (Microsoft extension).
DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION,
- /// \brief An ImportDecl recording a module import.
+ /// An ImportDecl recording a module import.
DECL_IMPORT,
- /// \brief An OMPThreadPrivateDecl record.
+ /// An OMPThreadPrivateDecl record.
DECL_OMP_THREADPRIVATE,
- /// \brief An EmptyDecl record.
+ /// An EmptyDecl record.
DECL_EMPTY,
- /// \brief An ObjCTypeParamDecl record.
+ /// An ObjCTypeParamDecl record.
DECL_OBJC_TYPE_PARAM,
- /// \brief An OMPCapturedExprDecl record.
+ /// An OMPCapturedExprDecl record.
DECL_OMP_CAPTUREDEXPR,
- /// \brief A PragmaCommentDecl record.
+ /// A PragmaCommentDecl record.
DECL_PRAGMA_COMMENT,
- /// \brief A PragmaDetectMismatchDecl record.
+ /// A PragmaDetectMismatchDecl record.
DECL_PRAGMA_DETECT_MISMATCH,
- /// \brief An OMPDeclareReductionDecl record.
+ /// An OMPDeclareReductionDecl record.
DECL_OMP_DECLARE_REDUCTION,
};
- /// \brief Record codes for each kind of statement or expression.
+ /// Record codes for each kind of statement or expression.
///
/// These constants describe the records that describe statements
/// or expressions. These records occur within type and declarations
@@ -1443,310 +1543,310 @@ namespace serialization {
/// describes a record for a specific statement or expression class in the
/// AST.
enum StmtCode {
- /// \brief A marker record that indicates that we are at the end
+ /// A marker record that indicates that we are at the end
/// of an expression.
STMT_STOP = 128,
- /// \brief A NULL expression.
+ /// A NULL expression.
STMT_NULL_PTR,
- /// \brief A reference to a previously [de]serialized Stmt record.
+ /// A reference to a previously [de]serialized Stmt record.
STMT_REF_PTR,
- /// \brief A NullStmt record.
+ /// A NullStmt record.
STMT_NULL,
- /// \brief A CompoundStmt record.
+ /// A CompoundStmt record.
STMT_COMPOUND,
- /// \brief A CaseStmt record.
+ /// A CaseStmt record.
STMT_CASE,
- /// \brief A DefaultStmt record.
+ /// A DefaultStmt record.
STMT_DEFAULT,
- /// \brief A LabelStmt record.
+ /// A LabelStmt record.
STMT_LABEL,
- /// \brief An AttributedStmt record.
+ /// An AttributedStmt record.
STMT_ATTRIBUTED,
- /// \brief An IfStmt record.
+ /// An IfStmt record.
STMT_IF,
- /// \brief A SwitchStmt record.
+ /// A SwitchStmt record.
STMT_SWITCH,
- /// \brief A WhileStmt record.
+ /// A WhileStmt record.
STMT_WHILE,
- /// \brief A DoStmt record.
+ /// A DoStmt record.
STMT_DO,
- /// \brief A ForStmt record.
+ /// A ForStmt record.
STMT_FOR,
- /// \brief A GotoStmt record.
+ /// A GotoStmt record.
STMT_GOTO,
- /// \brief An IndirectGotoStmt record.
+ /// An IndirectGotoStmt record.
STMT_INDIRECT_GOTO,
- /// \brief A ContinueStmt record.
+ /// A ContinueStmt record.
STMT_CONTINUE,
- /// \brief A BreakStmt record.
+ /// A BreakStmt record.
STMT_BREAK,
- /// \brief A ReturnStmt record.
+ /// A ReturnStmt record.
STMT_RETURN,
- /// \brief A DeclStmt record.
+ /// A DeclStmt record.
STMT_DECL,
- /// \brief A CapturedStmt record.
+ /// A CapturedStmt record.
STMT_CAPTURED,
- /// \brief A GCC-style AsmStmt record.
+ /// A GCC-style AsmStmt record.
STMT_GCCASM,
- /// \brief A MS-style AsmStmt record.
+ /// A MS-style AsmStmt record.
STMT_MSASM,
- /// \brief A PredefinedExpr record.
+ /// A PredefinedExpr record.
EXPR_PREDEFINED,
- /// \brief A DeclRefExpr record.
+ /// A DeclRefExpr record.
EXPR_DECL_REF,
- /// \brief An IntegerLiteral record.
+ /// An IntegerLiteral record.
EXPR_INTEGER_LITERAL,
- /// \brief A FloatingLiteral record.
+ /// A FloatingLiteral record.
EXPR_FLOATING_LITERAL,
- /// \brief An ImaginaryLiteral record.
+ /// An ImaginaryLiteral record.
EXPR_IMAGINARY_LITERAL,
- /// \brief A StringLiteral record.
+ /// A StringLiteral record.
EXPR_STRING_LITERAL,
- /// \brief A CharacterLiteral record.
+ /// A CharacterLiteral record.
EXPR_CHARACTER_LITERAL,
- /// \brief A ParenExpr record.
+ /// A ParenExpr record.
EXPR_PAREN,
- /// \brief A ParenListExpr record.
+ /// A ParenListExpr record.
EXPR_PAREN_LIST,
- /// \brief A UnaryOperator record.
+ /// A UnaryOperator record.
EXPR_UNARY_OPERATOR,
- /// \brief An OffsetOfExpr record.
+ /// An OffsetOfExpr record.
EXPR_OFFSETOF,
- /// \brief A SizefAlignOfExpr record.
+ /// A SizefAlignOfExpr record.
EXPR_SIZEOF_ALIGN_OF,
- /// \brief An ArraySubscriptExpr record.
+ /// An ArraySubscriptExpr record.
EXPR_ARRAY_SUBSCRIPT,
- /// \brief A CallExpr record.
+ /// A CallExpr record.
EXPR_CALL,
- /// \brief A MemberExpr record.
+ /// A MemberExpr record.
EXPR_MEMBER,
- /// \brief A BinaryOperator record.
+ /// A BinaryOperator record.
EXPR_BINARY_OPERATOR,
- /// \brief A CompoundAssignOperator record.
+ /// A CompoundAssignOperator record.
EXPR_COMPOUND_ASSIGN_OPERATOR,
- /// \brief A ConditionOperator record.
+ /// A ConditionOperator record.
EXPR_CONDITIONAL_OPERATOR,
- /// \brief An ImplicitCastExpr record.
+ /// An ImplicitCastExpr record.
EXPR_IMPLICIT_CAST,
- /// \brief A CStyleCastExpr record.
+ /// A CStyleCastExpr record.
EXPR_CSTYLE_CAST,
- /// \brief A CompoundLiteralExpr record.
+ /// A CompoundLiteralExpr record.
EXPR_COMPOUND_LITERAL,
- /// \brief An ExtVectorElementExpr record.
+ /// An ExtVectorElementExpr record.
EXPR_EXT_VECTOR_ELEMENT,
- /// \brief An InitListExpr record.
+ /// An InitListExpr record.
EXPR_INIT_LIST,
- /// \brief A DesignatedInitExpr record.
+ /// A DesignatedInitExpr record.
EXPR_DESIGNATED_INIT,
- /// \brief A DesignatedInitUpdateExpr record.
+ /// A DesignatedInitUpdateExpr record.
EXPR_DESIGNATED_INIT_UPDATE,
- /// \brief An NoInitExpr record.
+ /// An NoInitExpr record.
EXPR_NO_INIT,
- /// \brief An ArrayInitLoopExpr record.
+ /// An ArrayInitLoopExpr record.
EXPR_ARRAY_INIT_LOOP,
- /// \brief An ArrayInitIndexExpr record.
+ /// An ArrayInitIndexExpr record.
EXPR_ARRAY_INIT_INDEX,
- /// \brief An ImplicitValueInitExpr record.
+ /// An ImplicitValueInitExpr record.
EXPR_IMPLICIT_VALUE_INIT,
- /// \brief A VAArgExpr record.
+ /// A VAArgExpr record.
EXPR_VA_ARG,
- /// \brief An AddrLabelExpr record.
+ /// An AddrLabelExpr record.
EXPR_ADDR_LABEL,
- /// \brief A StmtExpr record.
+ /// A StmtExpr record.
EXPR_STMT,
- /// \brief A ChooseExpr record.
+ /// A ChooseExpr record.
EXPR_CHOOSE,
- /// \brief A GNUNullExpr record.
+ /// A GNUNullExpr record.
EXPR_GNU_NULL,
- /// \brief A ShuffleVectorExpr record.
+ /// A ShuffleVectorExpr record.
EXPR_SHUFFLE_VECTOR,
- /// \brief A ConvertVectorExpr record.
+ /// A ConvertVectorExpr record.
EXPR_CONVERT_VECTOR,
- /// \brief BlockExpr
+ /// BlockExpr
EXPR_BLOCK,
- /// \brief A GenericSelectionExpr record.
+ /// A GenericSelectionExpr record.
EXPR_GENERIC_SELECTION,
- /// \brief A PseudoObjectExpr record.
+ /// A PseudoObjectExpr record.
EXPR_PSEUDO_OBJECT,
- /// \brief An AtomicExpr record.
+ /// An AtomicExpr record.
EXPR_ATOMIC,
// Objective-C
- /// \brief An ObjCStringLiteral record.
+ /// An ObjCStringLiteral record.
EXPR_OBJC_STRING_LITERAL,
EXPR_OBJC_BOXED_EXPRESSION,
EXPR_OBJC_ARRAY_LITERAL,
EXPR_OBJC_DICTIONARY_LITERAL,
- /// \brief An ObjCEncodeExpr record.
+ /// An ObjCEncodeExpr record.
EXPR_OBJC_ENCODE,
- /// \brief An ObjCSelectorExpr record.
+ /// An ObjCSelectorExpr record.
EXPR_OBJC_SELECTOR_EXPR,
- /// \brief An ObjCProtocolExpr record.
+ /// An ObjCProtocolExpr record.
EXPR_OBJC_PROTOCOL_EXPR,
- /// \brief An ObjCIvarRefExpr record.
+ /// An ObjCIvarRefExpr record.
EXPR_OBJC_IVAR_REF_EXPR,
- /// \brief An ObjCPropertyRefExpr record.
+ /// An ObjCPropertyRefExpr record.
EXPR_OBJC_PROPERTY_REF_EXPR,
- /// \brief An ObjCSubscriptRefExpr record.
+ /// An ObjCSubscriptRefExpr record.
EXPR_OBJC_SUBSCRIPT_REF_EXPR,
- /// \brief UNUSED
+ /// UNUSED
EXPR_OBJC_KVC_REF_EXPR,
- /// \brief An ObjCMessageExpr record.
+ /// An ObjCMessageExpr record.
EXPR_OBJC_MESSAGE_EXPR,
- /// \brief An ObjCIsa Expr record.
+ /// An ObjCIsa Expr record.
EXPR_OBJC_ISA,
- /// \brief An ObjCIndirectCopyRestoreExpr record.
+ /// An ObjCIndirectCopyRestoreExpr record.
EXPR_OBJC_INDIRECT_COPY_RESTORE,
- /// \brief An ObjCForCollectionStmt record.
+ /// An ObjCForCollectionStmt record.
STMT_OBJC_FOR_COLLECTION,
- /// \brief An ObjCAtCatchStmt record.
+ /// An ObjCAtCatchStmt record.
STMT_OBJC_CATCH,
- /// \brief An ObjCAtFinallyStmt record.
+ /// An ObjCAtFinallyStmt record.
STMT_OBJC_FINALLY,
- /// \brief An ObjCAtTryStmt record.
+ /// An ObjCAtTryStmt record.
STMT_OBJC_AT_TRY,
- /// \brief An ObjCAtSynchronizedStmt record.
+ /// An ObjCAtSynchronizedStmt record.
STMT_OBJC_AT_SYNCHRONIZED,
- /// \brief An ObjCAtThrowStmt record.
+ /// An ObjCAtThrowStmt record.
STMT_OBJC_AT_THROW,
- /// \brief An ObjCAutoreleasePoolStmt record.
+ /// An ObjCAutoreleasePoolStmt record.
STMT_OBJC_AUTORELEASE_POOL,
- /// \brief An ObjCBoolLiteralExpr record.
+ /// An ObjCBoolLiteralExpr record.
EXPR_OBJC_BOOL_LITERAL,
- /// \brief An ObjCAvailabilityCheckExpr record.
+ /// An ObjCAvailabilityCheckExpr record.
EXPR_OBJC_AVAILABILITY_CHECK,
// C++
- /// \brief A CXXCatchStmt record.
+ /// A CXXCatchStmt record.
STMT_CXX_CATCH,
- /// \brief A CXXTryStmt record.
+ /// A CXXTryStmt record.
STMT_CXX_TRY,
- /// \brief A CXXForRangeStmt record.
+ /// A CXXForRangeStmt record.
STMT_CXX_FOR_RANGE,
- /// \brief A CXXOperatorCallExpr record.
+ /// A CXXOperatorCallExpr record.
EXPR_CXX_OPERATOR_CALL,
- /// \brief A CXXMemberCallExpr record.
+ /// A CXXMemberCallExpr record.
EXPR_CXX_MEMBER_CALL,
- /// \brief A CXXConstructExpr record.
+ /// A CXXConstructExpr record.
EXPR_CXX_CONSTRUCT,
- /// \brief A CXXInheritedCtorInitExpr record.
+ /// A CXXInheritedCtorInitExpr record.
EXPR_CXX_INHERITED_CTOR_INIT,
- /// \brief A CXXTemporaryObjectExpr record.
+ /// A CXXTemporaryObjectExpr record.
EXPR_CXX_TEMPORARY_OBJECT,
- /// \brief A CXXStaticCastExpr record.
+ /// A CXXStaticCastExpr record.
EXPR_CXX_STATIC_CAST,
- /// \brief A CXXDynamicCastExpr record.
+ /// A CXXDynamicCastExpr record.
EXPR_CXX_DYNAMIC_CAST,
- /// \brief A CXXReinterpretCastExpr record.
+ /// A CXXReinterpretCastExpr record.
EXPR_CXX_REINTERPRET_CAST,
- /// \brief A CXXConstCastExpr record.
+ /// A CXXConstCastExpr record.
EXPR_CXX_CONST_CAST,
- /// \brief A CXXFunctionalCastExpr record.
+ /// A CXXFunctionalCastExpr record.
EXPR_CXX_FUNCTIONAL_CAST,
- /// \brief A UserDefinedLiteral record.
+ /// A UserDefinedLiteral record.
EXPR_USER_DEFINED_LITERAL,
- /// \brief A CXXStdInitializerListExpr record.
+ /// A CXXStdInitializerListExpr record.
EXPR_CXX_STD_INITIALIZER_LIST,
- /// \brief A CXXBoolLiteralExpr record.
+ /// A CXXBoolLiteralExpr record.
EXPR_CXX_BOOL_LITERAL,
EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr
@@ -1865,24 +1965,24 @@ namespace serialization {
EXPR_DEPENDENT_COAWAIT,
};
- /// \brief The kinds of designators that can occur in a
+ /// The kinds of designators that can occur in a
/// DesignatedInitExpr.
enum DesignatorTypes {
- /// \brief Field designator where only the field name is known.
+ /// Field designator where only the field name is known.
DESIG_FIELD_NAME = 0,
- /// \brief Field designator where the field has been resolved to
+ /// Field designator where the field has been resolved to
/// a declaration.
DESIG_FIELD_DECL = 1,
- /// \brief Array designator.
+ /// Array designator.
DESIG_ARRAY = 2,
- /// \brief GNU array range designator.
+ /// GNU array range designator.
DESIG_ARRAY_RANGE = 3
};
- /// \brief The different kinds of data that can occur in a
+ /// The different kinds of data that can occur in a
/// CtorInitializer.
enum CtorInitializerType {
CTOR_INITIALIZER_BASE,
@@ -1891,7 +1991,7 @@ namespace serialization {
CTOR_INITIALIZER_INDIRECT_MEMBER
};
- /// \brief Describes the redeclarations of a declaration.
+ /// Describes the redeclarations of a declaration.
struct LocalRedeclarationsInfo {
// The ID of the first declaration
DeclID FirstID;
@@ -1920,7 +2020,7 @@ namespace serialization {
}
};
- /// \brief Describes the categories of an Objective-C class.
+ /// Describes the categories of an Objective-C class.
struct ObjCCategoriesInfo {
// The ID of the definition
DeclID DefinitionID;
@@ -1949,7 +2049,7 @@ namespace serialization {
}
};
- /// \brief A key used when looking up entities by \ref DeclarationName.
+ /// A key used when looking up entities by \ref DeclarationName.
///
/// Different \ref DeclarationNames are mapped to different keys, but the
/// same key can occasionally represent multiple names (for names that
diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h
index c26f3e0b425e4..c462a90dde549 100644
--- a/include/clang/Serialization/ASTDeserializationListener.h
+++ b/include/clang/Serialization/ASTDeserializationListener.h
@@ -32,28 +32,28 @@ class ASTDeserializationListener {
public:
virtual ~ASTDeserializationListener();
- /// \brief The ASTReader was initialized.
+ /// The ASTReader was initialized.
virtual void ReaderInitialized(ASTReader *Reader) { }
- /// \brief An identifier was deserialized from the AST file.
+ /// An identifier was deserialized from the AST file.
virtual void IdentifierRead(serialization::IdentID ID,
IdentifierInfo *II) { }
- /// \brief A macro was read from the AST file.
+ /// A macro was read from the AST file.
virtual void MacroRead(serialization::MacroID ID, MacroInfo *MI) { }
- /// \brief A type was deserialized from the AST file. The ID here has the
+ /// A type was deserialized from the AST file. The ID here has the
/// qualifier bits already removed, and T is guaranteed to be locally
/// unqualified.
virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { }
- /// \brief A decl was deserialized from the AST file.
+ /// A decl was deserialized from the AST file.
virtual void DeclRead(serialization::DeclID ID, const Decl *D) { }
- /// \brief A selector was read from the AST file.
+ /// A selector was read from the AST file.
virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) {}
- /// \brief A macro definition was read from the AST file.
+ /// A macro definition was read from the AST file.
virtual void MacroDefinitionRead(serialization::PreprocessedEntityID,
MacroDefinitionRecord *MD) {}
- /// \brief A module definition was read from the AST file.
+ /// A module definition was read from the AST file.
virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) {}
- /// \brief A module import was read from the AST file.
+ /// A module import was read from the AST file.
virtual void ModuleImportRead(serialization::SubmoduleID ID,
SourceLocation ImportLoc) {}
};
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 37920fc143ea7..82a74a64443d6 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -14,20 +14,20 @@
#ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_H
#define LLVM_CLANG_SERIALIZATION_ASTREADER_H
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/OpenCLOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Version.h"
-#include "clang/Basic/VersionTuple.h"
#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/PreprocessingRecord.h"
@@ -61,6 +61,7 @@
#include "llvm/Support/Endian.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Timer.h"
+#include "llvm/Support/VersionTuple.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
@@ -79,9 +80,6 @@ class ASTContext;
class ASTDeserializationListener;
class ASTReader;
class ASTRecordReader;
-class CXXBaseSpecifier;
-class CXXConstructorDecl;
-class CXXCtorInitializer;
class CXXTemporary;
class Decl;
class DeclaratorDecl;
@@ -102,7 +100,6 @@ class MacroInfo;
class MemoryBufferCache;
class NamedDecl;
class NamespaceDecl;
-class NestedNameSpecifier;
class ObjCCategoryDecl;
class ObjCInterfaceDecl;
class PCHContainerReader;
@@ -120,7 +117,7 @@ class TypeSourceInfo;
class ValueDecl;
class VarDecl;
-/// \brief Abstract interface for callback invocations by the ASTReader.
+/// Abstract interface for callback invocations by the ASTReader.
///
/// While reading an AST file, the ASTReader will call the methods of the
/// listener to pass on specific information. Some of the listener methods can
@@ -130,7 +127,7 @@ class ASTReaderListener {
public:
virtual ~ASTReaderListener();
- /// \brief Receives the full Clang version information.
+ /// Receives the full Clang version information.
///
/// \returns true to indicate that the version is invalid. Subclasses should
/// generally defer to this implementation.
@@ -141,7 +138,7 @@ public:
virtual void ReadModuleName(StringRef ModuleName) {}
virtual void ReadModuleMapFile(StringRef ModuleMapPath) {}
- /// \brief Receives the language options.
+ /// Receives the language options.
///
/// \returns true to indicate the options are invalid or false otherwise.
virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
@@ -150,7 +147,7 @@ public:
return false;
}
- /// \brief Receives the target options.
+ /// Receives the target options.
///
/// \returns true to indicate the target options are invalid, or false
/// otherwise.
@@ -159,7 +156,7 @@ public:
return false;
}
- /// \brief Receives the diagnostic options.
+ /// Receives the diagnostic options.
///
/// \returns true to indicate the diagnostic options are invalid, or false
/// otherwise.
@@ -169,7 +166,7 @@ public:
return false;
}
- /// \brief Receives the file system options.
+ /// Receives the file system options.
///
/// \returns true to indicate the file system options are invalid, or false
/// otherwise.
@@ -178,7 +175,7 @@ public:
return false;
}
- /// \brief Receives the header search options.
+ /// Receives the header search options.
///
/// \returns true to indicate the header search options are invalid, or false
/// otherwise.
@@ -188,7 +185,7 @@ public:
return false;
}
- /// \brief Receives the preprocessor options.
+ /// Receives the preprocessor options.
///
/// \param SuggestedPredefines Can be filled in with the set of predefines
/// that are suggested by the preprocessor options. Typically only used when
@@ -202,7 +199,7 @@ public:
return false;
}
- /// \brief Receives __COUNTER__ value.
+ /// Receives __COUNTER__ value.
virtual void ReadCounter(const serialization::ModuleFile &M,
unsigned Value) {}
@@ -210,15 +207,15 @@ public:
virtual void visitModuleFile(StringRef Filename,
serialization::ModuleKind Kind) {}
- /// \brief Returns true if this \c ASTReaderListener wants to receive the
+ /// Returns true if this \c ASTReaderListener wants to receive the
/// input files of the AST file via \c visitInputFile, false otherwise.
virtual bool needsInputFileVisitation() { return false; }
- /// \brief Returns true if this \c ASTReaderListener wants to receive the
+ /// Returns true if this \c ASTReaderListener wants to receive the
/// system input files of the AST file via \c visitInputFile, false otherwise.
virtual bool needsSystemInputFileVisitation() { return false; }
- /// \brief if \c needsInputFileVisitation returns true, this is called for
+ /// if \c needsInputFileVisitation returns true, this is called for
/// each non-system input file of the AST File. If
/// \c needsSystemInputFileVisitation is true, then it is called for all
/// system input files as well.
@@ -229,11 +226,11 @@ public:
return true;
}
- /// \brief Returns true if this \c ASTReaderListener wants to receive the
+ /// Returns true if this \c ASTReaderListener wants to receive the
/// imports of the AST file via \c visitImport, false otherwise.
virtual bool needsImportVisitation() const { return false; }
- /// \brief If needsImportVisitation returns \c true, this is called for each
+ /// If needsImportVisitation returns \c true, this is called for each
/// AST file imported by this AST file.
virtual void visitImport(StringRef Filename) {}
@@ -242,7 +239,7 @@ public:
const ModuleFileExtensionMetadata &Metadata) {}
};
-/// \brief Simple wrapper class for chaining listeners.
+/// Simple wrapper class for chaining listeners.
class ChainedASTReaderListener : public ASTReaderListener {
std::unique_ptr<ASTReaderListener> First;
std::unique_ptr<ASTReaderListener> Second;
@@ -286,7 +283,7 @@ public:
const ModuleFileExtensionMetadata &Metadata) override;
};
-/// \brief ASTReaderListener implementation to validate the information of
+/// ASTReaderListener implementation to validate the information of
/// the PCH file against an initialized Preprocessor.
class PCHValidator : public ASTReaderListener {
Preprocessor &PP;
@@ -294,7 +291,7 @@ class PCHValidator : public ASTReaderListener {
public:
PCHValidator(Preprocessor &PP, ASTReader &Reader)
- : PP(PP), Reader(Reader) {}
+ : PP(PP), Reader(Reader) {}
bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
bool AllowCompatibleDifferences) override;
@@ -313,7 +310,7 @@ private:
void Error(const char *Msg);
};
-/// \brief ASTReaderListenter implementation to set SuggestedPredefines of
+/// ASTReaderListenter implementation to set SuggestedPredefines of
/// ASTReader which is required to use a pch file. This is the replacement
/// of PCHValidator or SimplePCHValidator when using a pch file without
/// validating it.
@@ -321,8 +318,7 @@ class SimpleASTReaderListener : public ASTReaderListener {
Preprocessor &PP;
public:
- SimpleASTReaderListener(Preprocessor &PP)
- : PP(PP) {}
+ SimpleASTReaderListener(Preprocessor &PP) : PP(PP) {}
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
std::string &SuggestedPredefines) override;
@@ -336,14 +332,14 @@ namespace reader {
class ASTIdentifierLookupTrait;
-/// \brief The on-disk hash table(s) used for DeclContext name lookup.
+/// The on-disk hash table(s) used for DeclContext name lookup.
struct DeclContextLookupTable;
} // namespace reader
} // namespace serialization
-/// \brief Reads an AST files chain containing the contents of a translation
+/// Reads an AST files chain containing the contents of a translation
/// unit.
///
/// The ASTReader class reads bitstreams (produced by the ASTWriter
@@ -364,7 +360,7 @@ class ASTReader
public ExternalSLocEntrySource
{
public:
- /// \brief Types of AST files.
+ /// Types of AST files.
friend class ASTDeclReader;
friend class ASTIdentifierIterator;
friend class ASTRecordReader;
@@ -379,31 +375,31 @@ public:
using RecordData = SmallVector<uint64_t, 64>;
using RecordDataImpl = SmallVectorImpl<uint64_t>;
- /// \brief The result of reading the control block of an AST file, which
+ /// The result of reading the control block of an AST file, which
/// can fail for various reasons.
enum ASTReadResult {
- /// \brief The control block was read successfully. Aside from failures,
+ /// The control block was read successfully. Aside from failures,
/// the AST file is safe to read into the current context.
Success,
- /// \brief The AST file itself appears corrupted.
+ /// The AST file itself appears corrupted.
Failure,
- /// \brief The AST file was missing.
+ /// The AST file was missing.
Missing,
- /// \brief The AST file is out-of-date relative to its input files,
+ /// The AST file is out-of-date relative to its input files,
/// and needs to be regenerated.
OutOfDate,
- /// \brief The AST file was written by a different version of Clang.
+ /// The AST file was written by a different version of Clang.
VersionMismatch,
- /// \brief The AST file was writtten with a different language/target
+ /// The AST file was writtten with a different language/target
/// configuration.
ConfigurationMismatch,
- /// \brief The AST file has errors.
+ /// The AST file has errors.
HadErrors
};
@@ -415,10 +411,10 @@ public:
using ModuleReverseIterator = ModuleManager::ModuleReverseIterator;
private:
- /// \brief The receiver of some callbacks invoked by ASTReader.
+ /// The receiver of some callbacks invoked by ASTReader.
std::unique_ptr<ASTReaderListener> Listener;
- /// \brief The receiver of deserialization events.
+ /// The receiver of deserialization events.
ASTDeserializationListener *DeserializationListener = nullptr;
bool OwnsDeserializationListener = false;
@@ -428,26 +424,26 @@ private:
const PCHContainerReader &PCHContainerRdr;
DiagnosticsEngine &Diags;
- /// \brief The semantic analysis object that will be processing the
+ /// The semantic analysis object that will be processing the
/// AST files and the translation unit that uses it.
Sema *SemaObj = nullptr;
- /// \brief The preprocessor that will be loading the source file.
+ /// The preprocessor that will be loading the source file.
Preprocessor &PP;
- /// \brief The AST context into which we'll read the AST files.
+ /// The AST context into which we'll read the AST files.
ASTContext *ContextObj = nullptr;
- /// \brief The AST consumer.
+ /// The AST consumer.
ASTConsumer *Consumer = nullptr;
- /// \brief The module manager which manages modules and their dependencies
+ /// The module manager which manages modules and their dependencies
ModuleManager ModuleMgr;
/// The cache that manages memory buffers for PCM files.
MemoryBufferCache &PCMCache;
- /// \brief A dummy identifier resolver used to merge TU-scope declarations in
+ /// A dummy identifier resolver used to merge TU-scope declarations in
/// C, for the cases where we don't have a Sema object to provide a real
/// identifier resolver.
IdentifierResolver DummyIdResolver;
@@ -455,31 +451,31 @@ private:
/// A mapping from extension block names to module file extensions.
llvm::StringMap<std::shared_ptr<ModuleFileExtension>> ModuleFileExtensions;
- /// \brief A timer used to track the time spent deserializing.
+ /// A timer used to track the time spent deserializing.
std::unique_ptr<llvm::Timer> ReadTimer;
- /// \brief The location where the module file will be considered as
+ /// The location where the module file will be considered as
/// imported from. For non-module AST types it should be invalid.
SourceLocation CurrentImportLoc;
- /// \brief The global module index, if loaded.
+ /// The global module index, if loaded.
std::unique_ptr<GlobalModuleIndex> GlobalIndex;
- /// \brief A map of global bit offsets to the module that stores entities
+ /// A map of global bit offsets to the module that stores entities
/// at those bit offsets.
ContinuousRangeMap<uint64_t, ModuleFile*, 4> GlobalBitOffsetsMap;
- /// \brief A map of negated SLocEntryIDs to the modules containing them.
+ /// A map of negated SLocEntryIDs to the modules containing them.
ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocEntryMap;
using GlobalSLocOffsetMapType =
ContinuousRangeMap<unsigned, ModuleFile *, 64>;
- /// \brief A map of reversed (SourceManager::MaxLoadedOffset - SLocOffset)
+ /// A map of reversed (SourceManager::MaxLoadedOffset - SLocOffset)
/// SourceLocation offsets to the modules containing them.
GlobalSLocOffsetMapType GlobalSLocOffsetMap;
- /// \brief Types that have already been loaded from the chain.
+ /// Types that have already been loaded from the chain.
///
/// When the pointer at index I is non-NULL, the type with
/// ID = (I + 1) << FastQual::Width has already been loaded
@@ -488,12 +484,12 @@ private:
using GlobalTypeMapType =
ContinuousRangeMap<serialization::TypeID, ModuleFile *, 4>;
- /// \brief Mapping from global type IDs to the module in which the
+ /// Mapping from global type IDs to the module in which the
/// type resides along with the offset that should be added to the
/// global type ID to produce a local ID.
GlobalTypeMapType GlobalTypeMap;
- /// \brief Declarations that have already been loaded from the chain.
+ /// Declarations that have already been loaded from the chain.
///
/// When the pointer at index I is non-NULL, the declaration with ID
/// = I + 1 has already been loaded.
@@ -502,7 +498,7 @@ private:
using GlobalDeclMapType =
ContinuousRangeMap<serialization::DeclID, ModuleFile *, 4>;
- /// \brief Mapping from global declaration IDs to the module in which the
+ /// Mapping from global declaration IDs to the module in which the
/// declaration resides.
GlobalDeclMapType GlobalDeclMap;
@@ -511,7 +507,7 @@ private:
using DeclUpdateOffsetsMap =
llvm::DenseMap<serialization::DeclID, FileOffsetsTy>;
- /// \brief Declarations that have modifications residing in a later file
+ /// Declarations that have modifications residing in a later file
/// in the chain.
DeclUpdateOffsetsMap DeclUpdateOffsets;
@@ -527,30 +523,30 @@ private:
: D(D), ID(ID), JustLoaded(JustLoaded) {}
};
- /// \brief Declaration updates for already-loaded declarations that we need
+ /// Declaration updates for already-loaded declarations that we need
/// to apply once we finish processing an import.
llvm::SmallVector<PendingUpdateRecord, 16> PendingUpdateRecords;
enum class PendingFakeDefinitionKind { NotFake, Fake, FakeLoaded };
- /// \brief The DefinitionData pointers that we faked up for class definitions
+ /// The DefinitionData pointers that we faked up for class definitions
/// that we needed but hadn't loaded yet.
llvm::DenseMap<void *, PendingFakeDefinitionKind> PendingFakeDefinitionData;
- /// \brief Exception specification updates that have been loaded but not yet
+ /// Exception specification updates that have been loaded but not yet
/// propagated across the relevant redeclaration chain. The map key is the
/// canonical declaration (used only for deduplication) and the value is a
/// declaration that has an exception specification.
llvm::SmallMapVector<Decl *, FunctionDecl *, 4> PendingExceptionSpecUpdates;
- /// \brief Declarations that have been imported and have typedef names for
+ /// Declarations that have been imported and have typedef names for
/// linkage purposes.
llvm::DenseMap<std::pair<DeclContext *, IdentifierInfo *>, NamedDecl *>
ImportedTypedefNamesForLinkage;
- /// \brief Mergeable declaration contexts that have anonymous declarations
+ /// Mergeable declaration contexts that have anonymous declarations
/// within them, and those anonymous declarations.
- llvm::DenseMap<DeclContext*, llvm::SmallVector<NamedDecl*, 2>>
+ llvm::DenseMap<Decl*, llvm::SmallVector<NamedDecl*, 2>>
AnonymousDeclarationsForMerging;
struct FileDeclsInfo {
@@ -559,24 +555,24 @@ private:
FileDeclsInfo() = default;
FileDeclsInfo(ModuleFile *Mod, ArrayRef<serialization::LocalDeclID> Decls)
- : Mod(Mod), Decls(Decls) {}
+ : Mod(Mod), Decls(Decls) {}
};
- /// \brief Map from a FileID to the file-level declarations that it contains.
+ /// Map from a FileID to the file-level declarations that it contains.
llvm::DenseMap<FileID, FileDeclsInfo> FileDeclIDs;
- /// \brief An array of lexical contents of a declaration context, as a sequence of
+ /// An array of lexical contents of a declaration context, as a sequence of
/// Decl::Kind, DeclID pairs.
using LexicalContents = ArrayRef<llvm::support::unaligned_uint32_t>;
- /// \brief Map from a DeclContext to its lexical contents.
+ /// Map from a DeclContext to its lexical contents.
llvm::DenseMap<const DeclContext*, std::pair<ModuleFile*, LexicalContents>>
LexicalDecls;
- /// \brief Map from the TU to its lexical contents from each module file.
+ /// Map from the TU to its lexical contents from each module file.
std::vector<std::pair<ModuleFile*, LexicalContents>> TULexicalDecls;
- /// \brief Map from a DeclContext to its lookup tables.
+ /// Map from a DeclContext to its lookup tables.
llvm::DenseMap<const DeclContext *,
serialization::reader::DeclContextLookupTable> Lookups;
@@ -590,12 +586,12 @@ private:
};
using DeclContextVisibleUpdates = SmallVector<PendingVisibleUpdate, 1>;
- /// \brief Updates to the visible declarations of declaration contexts that
+ /// Updates to the visible declarations of declaration contexts that
/// haven't been loaded yet.
llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates>
PendingVisibleUpdates;
- /// \brief The set of C++ or Objective-C classes that have forward
+ /// The set of C++ or Objective-C classes that have forward
/// declarations that have not yet been linked to their definitions.
llvm::SmallPtrSet<Decl *, 4> PendingDefinitions;
@@ -604,24 +600,24 @@ private:
llvm::SmallDenseMap<Decl *, unsigned, 4>,
SmallVector<std::pair<Decl *, uint64_t>, 4>>;
- /// \brief Functions or methods that have bodies that will be attached.
+ /// Functions or methods that have bodies that will be attached.
PendingBodiesMap PendingBodies;
- /// \brief Definitions for which we have added merged definitions but not yet
+ /// Definitions for which we have added merged definitions but not yet
/// performed deduplication.
llvm::SetVector<NamedDecl *> PendingMergedDefinitionsToDeduplicate;
- /// \brief Read the record that describes the lexical contents of a DC.
+ /// Read the record that describes the lexical contents of a DC.
bool ReadLexicalDeclContextStorage(ModuleFile &M,
llvm::BitstreamCursor &Cursor,
uint64_t Offset, DeclContext *DC);
- /// \brief Read the record that describes the visible contents of a DC.
+ /// Read the record that describes the visible contents of a DC.
bool ReadVisibleDeclContextStorage(ModuleFile &M,
llvm::BitstreamCursor &Cursor,
uint64_t Offset, serialization::DeclID ID);
- /// \brief A vector containing identifiers that have already been
+ /// A vector containing identifiers that have already been
/// loaded.
///
/// If the pointer at index I is non-NULL, then it refers to the
@@ -632,12 +628,12 @@ private:
using GlobalIdentifierMapType =
ContinuousRangeMap<serialization::IdentID, ModuleFile *, 4>;
- /// \brief Mapping from global identifier IDs to the module in which the
+ /// Mapping from global identifier IDs to the module in which the
/// identifier resides along with the offset that should be added to the
/// global identifier ID to produce a local ID.
GlobalIdentifierMapType GlobalIdentifierMap;
- /// \brief A vector containing macros that have already been
+ /// A vector containing macros that have already been
/// loaded.
///
/// If the pointer at index I is non-NULL, then it refers to the
@@ -648,7 +644,7 @@ private:
using LoadedMacroInfo =
std::pair<IdentifierInfo *, serialization::SubmoduleID>;
- /// \brief A set of #undef directives that we have loaded; used to
+ /// A set of #undef directives that we have loaded; used to
/// deduplicate the same #undef information coming from multiple module
/// files.
llvm::DenseSet<LoadedMacroInfo> LoadedUndefs;
@@ -656,12 +652,12 @@ private:
using GlobalMacroMapType =
ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4>;
- /// \brief Mapping from global macro IDs to the module in which the
+ /// Mapping from global macro IDs to the module in which the
/// macro resides along with the offset that should be added to the
/// global macro ID to produce a local ID.
GlobalMacroMapType GlobalMacroMap;
- /// \brief A vector containing submodules that have already been loaded.
+ /// A vector containing submodules that have already been loaded.
///
/// This vector is indexed by the Submodule ID (-1). NULL submodule entries
/// indicate that the particular submodule ID has not yet been loaded.
@@ -670,45 +666,45 @@ private:
using GlobalSubmoduleMapType =
ContinuousRangeMap<serialization::SubmoduleID, ModuleFile *, 4>;
- /// \brief Mapping from global submodule IDs to the module file in which the
+ /// Mapping from global submodule IDs to the module file in which the
/// submodule resides along with the offset that should be added to the
/// global submodule ID to produce a local ID.
GlobalSubmoduleMapType GlobalSubmoduleMap;
- /// \brief A set of hidden declarations.
+ /// A set of hidden declarations.
using HiddenNames = SmallVector<Decl *, 2>;
using HiddenNamesMapType = llvm::DenseMap<Module *, HiddenNames>;
- /// \brief A mapping from each of the hidden submodules to the deserialized
+ /// A mapping from each of the hidden submodules to the deserialized
/// declarations in that submodule that could be made visible.
HiddenNamesMapType HiddenNamesMap;
- /// \brief A module import, export, or conflict that hasn't yet been resolved.
+ /// A module import, export, or conflict that hasn't yet been resolved.
struct UnresolvedModuleRef {
- /// \brief The file in which this module resides.
+ /// The file in which this module resides.
ModuleFile *File;
- /// \brief The module that is importing or exporting.
+ /// The module that is importing or exporting.
Module *Mod;
- /// \brief The kind of module reference.
+ /// The kind of module reference.
enum { Import, Export, Conflict } Kind;
- /// \brief The local ID of the module that is being exported.
+ /// The local ID of the module that is being exported.
unsigned ID;
- /// \brief Whether this is a wildcard export.
+ /// Whether this is a wildcard export.
unsigned IsWildcard : 1;
- /// \brief String data.
+ /// String data.
StringRef String;
};
- /// \brief The set of module imports and exports that still need to be
+ /// The set of module imports and exports that still need to be
/// resolved.
SmallVector<UnresolvedModuleRef, 2> UnresolvedModuleRefs;
- /// \brief A vector containing selectors that have already been loaded.
+ /// A vector containing selectors that have already been loaded.
///
/// This vector is indexed by the Selector ID (-1). NULL selector
/// entries indicate that the particular selector ID has not yet
@@ -718,11 +714,11 @@ private:
using GlobalSelectorMapType =
ContinuousRangeMap<serialization::SelectorID, ModuleFile *, 4>;
- /// \brief Mapping from global selector IDs to the module in which the
+ /// Mapping from global selector IDs to the module in which the
/// global selector ID to produce a local ID.
GlobalSelectorMapType GlobalSelectorMap;
- /// \brief The generation number of the last time we loaded data from the
+ /// The generation number of the last time we loaded data from the
/// global method pool for this selector.
llvm::DenseMap<Selector, unsigned> SelectorGeneration;
@@ -741,23 +737,30 @@ private:
using PendingMacroIDsMap =
llvm::MapVector<IdentifierInfo *, SmallVector<PendingMacroInfo, 2>>;
- /// \brief Mapping from identifiers that have a macro history to the global
+ /// Mapping from identifiers that have a macro history to the global
/// IDs have not yet been deserialized to the global IDs of those macros.
PendingMacroIDsMap PendingMacroIDs;
using GlobalPreprocessedEntityMapType =
ContinuousRangeMap<unsigned, ModuleFile *, 4>;
- /// \brief Mapping from global preprocessing entity IDs to the module in
+ /// Mapping from global preprocessing entity IDs to the module in
/// which the preprocessed entity resides along with the offset that should be
/// added to the global preprocessing entity ID to produce a local ID.
GlobalPreprocessedEntityMapType GlobalPreprocessedEntityMap;
+ using GlobalSkippedRangeMapType =
+ ContinuousRangeMap<unsigned, ModuleFile *, 4>;
+
+ /// Mapping from global skipped range base IDs to the module in which
+ /// the skipped ranges reside.
+ GlobalSkippedRangeMapType GlobalSkippedRangeMap;
+
/// \name CodeGen-relevant special data
- /// \brief Fields containing data that is relevant to CodeGen.
+ /// Fields containing data that is relevant to CodeGen.
//@{
- /// \brief The IDs of all declarations that fulfill the criteria of
+ /// The IDs of all declarations that fulfill the criteria of
/// "interesting" decls.
///
/// This contains the data loaded from all EAGERLY_DESERIALIZED_DECLS blocks
@@ -765,21 +768,21 @@ private:
/// the consumer eagerly.
SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
- /// \brief The IDs of all tentative definitions stored in the chain.
+ /// The IDs of all tentative definitions stored in the chain.
///
/// Sema keeps track of all tentative definitions in a TU because it has to
/// complete them and pass them on to CodeGen. Thus, tentative definitions in
/// the PCH chain must be eagerly deserialized.
SmallVector<uint64_t, 16> TentativeDefinitions;
- /// \brief The IDs of all CXXRecordDecls stored in the chain whose VTables are
+ /// The IDs of all CXXRecordDecls stored in the chain whose VTables are
/// used.
///
/// CodeGen has to emit VTables for these records, so they have to be eagerly
/// deserialized.
SmallVector<uint64_t, 64> VTableUses;
- /// \brief A snapshot of the pending instantiations in the chain.
+ /// A snapshot of the pending instantiations in the chain.
///
/// This record tracks the instantiations that Sema has to perform at the
/// end of the TU. It consists of a pair of values for every pending
@@ -790,26 +793,26 @@ private:
//@}
/// \name DiagnosticsEngine-relevant special data
- /// \brief Fields containing data that is used for generating diagnostics
+ /// Fields containing data that is used for generating diagnostics
//@{
- /// \brief A snapshot of Sema's unused file-scoped variable tracking, for
+ /// A snapshot of Sema's unused file-scoped variable tracking, for
/// generating warnings.
SmallVector<uint64_t, 16> UnusedFileScopedDecls;
- /// \brief A list of all the delegating constructors we've seen, to diagnose
+ /// A list of all the delegating constructors we've seen, to diagnose
/// cycles.
SmallVector<uint64_t, 4> DelegatingCtorDecls;
- /// \brief Method selectors used in a @selector expression. Used for
+ /// Method selectors used in a @selector expression. Used for
/// implementation of -Wselector.
SmallVector<uint64_t, 64> ReferencedSelectorsData;
- /// \brief A snapshot of Sema's weak undeclared identifier tracking, for
+ /// A snapshot of Sema's weak undeclared identifier tracking, for
/// generating warnings.
SmallVector<uint64_t, 64> WeakUndeclaredIdentifiers;
- /// \brief The IDs of type aliases for ext_vectors that exist in the chain.
+ /// The IDs of type aliases for ext_vectors that exist in the chain.
///
/// Used by Sema for finding sugared names for ext_vectors in diagnostics.
SmallVector<uint64_t, 4> ExtVectorDecls;
@@ -817,48 +820,48 @@ private:
//@}
/// \name Sema-relevant special data
- /// \brief Fields containing data that is used for semantic analysis
+ /// Fields containing data that is used for semantic analysis
//@{
- /// \brief The IDs of all potentially unused typedef names in the chain.
+ /// The IDs of all potentially unused typedef names in the chain.
///
/// Sema tracks these to emit warnings.
SmallVector<uint64_t, 16> UnusedLocalTypedefNameCandidates;
- /// \brief Our current depth in #pragma cuda force_host_device begin/end
+ /// Our current depth in #pragma cuda force_host_device begin/end
/// macros.
unsigned ForceCUDAHostDeviceDepth = 0;
- /// \brief The IDs of the declarations Sema stores directly.
+ /// The IDs of the declarations Sema stores directly.
///
/// Sema tracks a few important decls, such as namespace std, directly.
SmallVector<uint64_t, 4> SemaDeclRefs;
- /// \brief The IDs of the types ASTContext stores directly.
+ /// The IDs of the types ASTContext stores directly.
///
/// The AST context tracks a few important types, such as va_list, directly.
SmallVector<uint64_t, 16> SpecialTypes;
- /// \brief The IDs of CUDA-specific declarations ASTContext stores directly.
+ /// The IDs of CUDA-specific declarations ASTContext stores directly.
///
/// The AST context tracks a few important decls, currently cudaConfigureCall,
/// directly.
SmallVector<uint64_t, 2> CUDASpecialDeclRefs;
- /// \brief The floating point pragma option settings.
+ /// The floating point pragma option settings.
SmallVector<uint64_t, 1> FPPragmaOptions;
- /// \brief The pragma clang optimize location (if the pragma state is "off").
+ /// The pragma clang optimize location (if the pragma state is "off").
SourceLocation OptimizeOffPragmaLocation;
- /// \brief The PragmaMSStructKind pragma ms_struct state if set, or -1.
+ /// The PragmaMSStructKind pragma ms_struct state if set, or -1.
int PragmaMSStructState = -1;
- /// \brief The PragmaMSPointersToMembersKind pragma pointers_to_members state.
+ /// The PragmaMSPointersToMembersKind pragma pointers_to_members state.
int PragmaMSPointersToMembersState = -1;
SourceLocation PointersToMembersPragmaLocation;
- /// \brief The pragma pack state.
+ /// The pragma pack state.
Optional<unsigned> PragmaPackCurrentValue;
SourceLocation PragmaPackCurrentLocation;
struct PragmaPackStackEntry {
@@ -870,26 +873,26 @@ private:
llvm::SmallVector<PragmaPackStackEntry, 2> PragmaPackStack;
llvm::SmallVector<std::string, 2> PragmaPackStrings;
- /// \brief The OpenCL extension settings.
+ /// The OpenCL extension settings.
OpenCLOptions OpenCLExtensions;
- /// \brief Extensions required by an OpenCL type.
+ /// Extensions required by an OpenCL type.
llvm::DenseMap<const Type *, std::set<std::string>> OpenCLTypeExtMap;
- /// \brief Extensions required by an OpenCL declaration.
+ /// Extensions required by an OpenCL declaration.
llvm::DenseMap<const Decl *, std::set<std::string>> OpenCLDeclExtMap;
- /// \brief A list of the namespaces we've seen.
+ /// A list of the namespaces we've seen.
SmallVector<uint64_t, 4> KnownNamespaces;
- /// \brief A list of undefined decls with internal linkage followed by the
+ /// A list of undefined decls with internal linkage followed by the
/// SourceLocation of a matching ODR-use.
SmallVector<uint64_t, 8> UndefinedButUsed;
- /// \brief Delete expressions to analyze at the end of translation unit.
+ /// Delete expressions to analyze at the end of translation unit.
SmallVector<uint64_t, 8> DelayedDeleteExprs;
- // \brief A list of late parsed template function data.
+ // A list of late parsed template function data.
SmallVector<uint64_t, 1> LateParsedTemplates;
public:
@@ -898,45 +901,45 @@ public:
SourceLocation ImportLoc;
ImportedSubmodule(serialization::SubmoduleID ID, SourceLocation ImportLoc)
- : ID(ID), ImportLoc(ImportLoc) {}
+ : ID(ID), ImportLoc(ImportLoc) {}
};
private:
- /// \brief A list of modules that were imported by precompiled headers or
+ /// A list of modules that were imported by precompiled headers or
/// any other non-module AST file.
SmallVector<ImportedSubmodule, 2> ImportedModules;
//@}
- /// \brief The system include root to be used when loading the
+ /// The system include root to be used when loading the
/// precompiled header.
std::string isysroot;
- /// \brief Whether to disable the normal validation performed on precompiled
+ /// Whether to disable the normal validation performed on precompiled
/// headers when they are loaded.
bool DisableValidation;
- /// \brief Whether to accept an AST file with compiler errors.
+ /// Whether to accept an AST file with compiler errors.
bool AllowASTWithCompilerErrors;
- /// \brief Whether to accept an AST file that has a different configuration
+ /// Whether to accept an AST file that has a different configuration
/// from the current compiler instance.
bool AllowConfigurationMismatch;
- /// \brief Whether validate system input files.
+ /// Whether validate system input files.
bool ValidateSystemInputs;
- /// \brief Whether we are allowed to use the global module index.
+ /// Whether we are allowed to use the global module index.
bool UseGlobalIndex;
- /// \brief Whether we have tried loading the global module index yet.
+ /// Whether we have tried loading the global module index yet.
bool TriedLoadingGlobalIndex = false;
- ///\brief Whether we are currently processing update records.
+ ///Whether we are currently processing update records.
bool ProcessingUpdateRecords = false;
using SwitchCaseMapTy = llvm::DenseMap<unsigned, SwitchCase *>;
- /// \brief Mapping from switch-case IDs in the chain to switch-case statements
+ /// Mapping from switch-case IDs in the chain to switch-case statements
///
/// Statements usually don't have IDs, but switch cases need them, so that the
/// switch statement can refer to them.
@@ -944,56 +947,56 @@ private:
SwitchCaseMapTy *CurrSwitchCaseStmts;
- /// \brief The number of source location entries de-serialized from
+ /// The number of source location entries de-serialized from
/// the PCH file.
unsigned NumSLocEntriesRead = 0;
- /// \brief The number of source location entries in the chain.
+ /// The number of source location entries in the chain.
unsigned TotalNumSLocEntries = 0;
- /// \brief The number of statements (and expressions) de-serialized
+ /// The number of statements (and expressions) de-serialized
/// from the chain.
unsigned NumStatementsRead = 0;
- /// \brief The total number of statements (and expressions) stored
+ /// The total number of statements (and expressions) stored
/// in the chain.
unsigned TotalNumStatements = 0;
- /// \brief The number of macros de-serialized from the chain.
+ /// The number of macros de-serialized from the chain.
unsigned NumMacrosRead = 0;
- /// \brief The total number of macros stored in the chain.
+ /// The total number of macros stored in the chain.
unsigned TotalNumMacros = 0;
- /// \brief The number of lookups into identifier tables.
+ /// The number of lookups into identifier tables.
unsigned NumIdentifierLookups = 0;
- /// \brief The number of lookups into identifier tables that succeed.
+ /// The number of lookups into identifier tables that succeed.
unsigned NumIdentifierLookupHits = 0;
- /// \brief The number of selectors that have been read.
+ /// The number of selectors that have been read.
unsigned NumSelectorsRead = 0;
- /// \brief The number of method pool entries that have been read.
+ /// The number of method pool entries that have been read.
unsigned NumMethodPoolEntriesRead = 0;
- /// \brief The number of times we have looked up a selector in the method
+ /// The number of times we have looked up a selector in the method
/// pool.
unsigned NumMethodPoolLookups = 0;
- /// \brief The number of times we have looked up a selector in the method
+ /// The number of times we have looked up a selector in the method
/// pool and found something.
unsigned NumMethodPoolHits = 0;
- /// \brief The number of times we have looked up a selector in the method
+ /// The number of times we have looked up a selector in the method
/// pool within a specific module.
unsigned NumMethodPoolTableLookups = 0;
- /// \brief The number of times we have looked up a selector in the method
+ /// The number of times we have looked up a selector in the method
/// pool within a specific module and found something.
unsigned NumMethodPoolTableHits = 0;
- /// \brief The total number of method pool entries in the selector table.
+ /// The total number of method pool entries in the selector table.
unsigned TotalNumMethodPoolEntries = 0;
/// Number of lexical decl contexts read/total.
@@ -1005,16 +1008,16 @@ private:
/// Total size of modules, in bits, currently loaded
uint64_t TotalModulesSizeInBits = 0;
- /// \brief Number of Decl/types that are currently deserializing.
+ /// Number of Decl/types that are currently deserializing.
unsigned NumCurrentElementsDeserializing = 0;
- /// \brief Set true while we are in the process of passing deserialized
+ /// Set true while we are in the process of passing deserialized
/// "interesting" decls to consumer inside FinishedDeserializing().
/// This is used as a guard to avoid recursively repeating the process of
/// passing decls to consumer.
bool PassingDeclsToConsumer = false;
- /// \brief The set of identifiers that were read while the AST reader was
+ /// The set of identifiers that were read while the AST reader was
/// (recursively) loading declarations.
///
/// The declarations on the identifier chain for these identifiers will be
@@ -1022,12 +1025,12 @@ private:
llvm::MapVector<IdentifierInfo *, SmallVector<uint32_t, 4>>
PendingIdentifierInfos;
- /// \brief The set of lookup results that we have faked in order to support
+ /// The set of lookup results that we have faked in order to support
/// merging of partially deserialized decls but that we have not yet removed.
llvm::SmallMapVector<IdentifierInfo *, SmallVector<NamedDecl*, 2>, 16>
PendingFakeLookupResults;
- /// \brief The generation number of each identifier, which keeps track of
+ /// The generation number of each identifier, which keeps track of
/// the last time we loaded information about this identifier.
llvm::DenseMap<IdentifierInfo *, unsigned> IdentifierGeneration;
@@ -1045,7 +1048,7 @@ private:
bool hasPendingBody() { return DeclHasPendingBody; }
};
- /// \brief Contains declarations and definitions that could be
+ /// Contains declarations and definitions that could be
/// "interesting" to the ASTConsumer, when we get that AST consumer.
///
/// "Interesting" declarations are those that have data that may
@@ -1053,16 +1056,16 @@ private:
/// Objective-C protocols.
std::deque<InterestingDecl> PotentiallyInterestingDecls;
- /// \brief The list of redeclaration chains that still need to be
+ /// The list of redeclaration chains that still need to be
/// reconstructed, and the local offset to the corresponding list
/// of redeclarations.
SmallVector<std::pair<Decl *, uint64_t>, 16> PendingDeclChains;
- /// \brief The list of canonical declarations whose redeclaration chains
+ /// The list of canonical declarations whose redeclaration chains
/// need to be marked as incomplete once we're done deserializing things.
SmallVector<Decl *, 16> PendingIncompleteDeclChains;
- /// \brief The Decl IDs for the Sema/Lexical DeclContext of a Decl that has
+ /// The Decl IDs for the Sema/Lexical DeclContext of a Decl that has
/// been loaded but its DeclContext was not set yet.
struct PendingDeclContextInfo {
Decl *D;
@@ -1070,14 +1073,14 @@ private:
serialization::GlobalDeclID LexicalDC;
};
- /// \brief The set of Decls that have been loaded but their DeclContexts are
+ /// The set of Decls that have been loaded but their DeclContexts are
/// not set yet.
///
/// The DeclContexts for these Decls will be set once recursive loading has
/// been completed.
std::deque<PendingDeclContextInfo> PendingDeclContextInfos;
- /// \brief The set of NamedDecls that have been loaded, but are members of a
+ /// The set of NamedDecls that have been loaded, but are members of a
/// context that has been merged into another context where the corresponding
/// declaration is either missing or has not yet been loaded.
///
@@ -1088,22 +1091,26 @@ private:
using DataPointers =
std::pair<CXXRecordDecl *, struct CXXRecordDecl::DefinitionData *>;
- /// \brief Record definitions in which we found an ODR violation.
+ /// Record definitions in which we found an ODR violation.
llvm::SmallDenseMap<CXXRecordDecl *, llvm::SmallVector<DataPointers, 2>, 2>
PendingOdrMergeFailures;
- /// \brief Function definitions in which we found an ODR violation.
+ /// Function definitions in which we found an ODR violation.
llvm::SmallDenseMap<FunctionDecl *, llvm::SmallVector<FunctionDecl *, 2>, 2>
PendingFunctionOdrMergeFailures;
- /// \brief DeclContexts in which we have diagnosed an ODR violation.
+ /// Enum definitions in which we found an ODR violation.
+ llvm::SmallDenseMap<EnumDecl *, llvm::SmallVector<EnumDecl *, 2>, 2>
+ PendingEnumOdrMergeFailures;
+
+ /// DeclContexts in which we have diagnosed an ODR violation.
llvm::SmallPtrSet<DeclContext*, 2> DiagnosedOdrMergeFailures;
- /// \brief The set of Objective-C categories that have been deserialized
+ /// The set of Objective-C categories that have been deserialized
/// since the last time the declaration chains were linked.
llvm::SmallPtrSet<ObjCCategoryDecl *, 16> CategoriesDeserialized;
- /// \brief The set of Objective-C class definitions that have already been
+ /// The set of Objective-C class definitions that have already been
/// loaded, for which we will need to check for categories whenever a new
/// module is loaded.
SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded;
@@ -1111,41 +1118,41 @@ private:
using KeyDeclsMap =
llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2>>;
- /// \brief A mapping from canonical declarations to the set of global
+ /// A mapping from canonical declarations to the set of global
/// declaration IDs for key declaration that have been merged with that
/// canonical declaration. A key declaration is a formerly-canonical
/// declaration whose module did not import any other key declaration for that
/// entity. These are the IDs that we use as keys when finding redecl chains.
KeyDeclsMap KeyDecls;
- /// \brief A mapping from DeclContexts to the semantic DeclContext that we
+ /// A mapping from DeclContexts to the semantic DeclContext that we
/// are treating as the definition of the entity. This is used, for instance,
/// when merging implicit instantiations of class templates across modules.
llvm::DenseMap<DeclContext *, DeclContext *> MergedDeclContexts;
- /// \brief A mapping from canonical declarations of enums to their canonical
+ /// A mapping from canonical declarations of enums to their canonical
/// definitions. Only populated when using modules in C++.
llvm::DenseMap<EnumDecl *, EnumDecl *> EnumDefinitions;
- /// \brief When reading a Stmt tree, Stmt operands are placed in this stack.
+ /// When reading a Stmt tree, Stmt operands are placed in this stack.
SmallVector<Stmt *, 16> StmtStack;
- /// \brief What kind of records we are reading.
+ /// What kind of records we are reading.
enum ReadingKind {
Read_None, Read_Decl, Read_Type, Read_Stmt
};
- /// \brief What kind of records we are reading.
+ /// What kind of records we are reading.
ReadingKind ReadingKind = Read_None;
- /// \brief RAII object to change the reading kind.
+ /// RAII object to change the reading kind.
class ReadingKindTracker {
ASTReader &Reader;
enum ReadingKind PrevKind;
public:
ReadingKindTracker(enum ReadingKind newKind, ASTReader &reader)
- : Reader(reader), PrevKind(Reader.ReadingKind) {
+ : Reader(reader), PrevKind(Reader.ReadingKind) {
Reader.ReadingKind = newKind;
}
@@ -1154,14 +1161,14 @@ private:
~ReadingKindTracker() { Reader.ReadingKind = PrevKind; }
};
- /// \brief RAII object to mark the start of processing updates.
+ /// RAII object to mark the start of processing updates.
class ProcessingUpdatesRAIIObj {
ASTReader &Reader;
bool PrevState;
public:
ProcessingUpdatesRAIIObj(ASTReader &reader)
- : Reader(reader), PrevState(Reader.ProcessingUpdateRecords) {
+ : Reader(reader), PrevState(Reader.ProcessingUpdateRecords) {
Reader.ProcessingUpdateRecords = true;
}
@@ -1171,7 +1178,7 @@ private:
~ProcessingUpdatesRAIIObj() { Reader.ProcessingUpdateRecords = PrevState; }
};
- /// \brief Suggested contents of the predefines buffer, after this
+ /// Suggested contents of the predefines buffer, after this
/// PCH file has been processed.
///
/// In most cases, this string will be empty, because the predefines
@@ -1183,7 +1190,7 @@ private:
llvm::DenseMap<const Decl *, bool> DefinitionSource;
- /// \brief Reads a statement from the specified cursor.
+ /// Reads a statement from the specified cursor.
Stmt *ReadStmtFromStream(ModuleFile &F);
struct InputFileInfo {
@@ -1195,10 +1202,10 @@ private:
bool TopLevelModuleMap;
};
- /// \brief Reads the stored information about an input file.
+ /// Reads the stored information about an input file.
InputFileInfo readInputFileInfo(ModuleFile &F, unsigned ID);
- /// \brief Retrieve the file entry and 'overridden' bit for an input
+ /// Retrieve the file entry and 'overridden' bit for an input
/// file in the given module file.
serialization::InputFile getInputFile(ModuleFile &F, unsigned ID,
bool Complain = true);
@@ -1207,7 +1214,7 @@ public:
void ResolveImportedPath(ModuleFile &M, std::string &Filename);
static void ResolveImportedPath(std::string &Filename, StringRef Prefix);
- /// \brief Returns the first key declaration for the given declaration. This
+ /// Returns the first key declaration for the given declaration. This
/// is one that is formerly-canonical (or still canonical) and whose module
/// did not import any other key declaration of the entity.
Decl *getKeyDeclaration(Decl *D) {
@@ -1224,7 +1231,7 @@ public:
return getKeyDeclaration(const_cast<Decl*>(D));
}
- /// \brief Run a callback on each imported key declaration of \p D.
+ /// Run a callback on each imported key declaration of \p D.
template <typename Fn>
void forEachImportedKeyDecl(const Decl *D, Fn Visit) {
D = D->getCanonicalDecl();
@@ -1237,7 +1244,7 @@ public:
Visit(GetExistingDecl(ID));
}
- /// \brief Get the loaded lookup tables for \p Primary, if any.
+ /// Get the loaded lookup tables for \p Primary, if any.
const serialization::reader::DeclContextLookupTable *
getLoadedLookupTables(DeclContext *Primary) const;
@@ -1250,7 +1257,7 @@ private:
ImportedModule(ModuleFile *Mod,
ModuleFile *ImportedBy,
SourceLocation ImportLoc)
- : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) {}
+ : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) {}
};
ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type,
@@ -1314,8 +1321,7 @@ private:
ModuleFile *F;
uint64_t Offset;
- RecordLocation(ModuleFile *M, uint64_t O)
- : F(M), Offset(O) {}
+ RecordLocation(ModuleFile *M, uint64_t O) : F(M), Offset(O) {}
};
QualType readTypeRecord(unsigned Index);
@@ -1328,7 +1334,7 @@ private:
Decl *ReadDeclRecord(serialization::DeclID ID);
void markIncompleteDeclChain(Decl *Canon);
- /// \brief Returns the most recent declaration of a declaration (which must be
+ /// Returns the most recent declaration of a declaration (which must be
/// of a redeclarable kind) that is either local or has already been loaded
/// merged into its redecl chain.
Decl *getMostRecentExistingDecl(Decl *D);
@@ -1343,12 +1349,12 @@ private:
RecordLocation getLocalBitOffset(uint64_t GlobalOffset);
uint64_t getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset);
- /// \brief Returns the first preprocessed entity ID that begins or ends after
+ /// Returns the first preprocessed entity ID that begins or ends after
/// \arg Loc.
serialization::PreprocessedEntityID
findPreprocessedEntity(SourceLocation Loc, bool EndsAfter) const;
- /// \brief Find the next module that contains entities and return the ID
+ /// Find the next module that contains entities and return the ID
/// of the first entry.
///
/// \param SLocMapI points at a chunk of a module that contains no
@@ -1358,12 +1364,12 @@ private:
findNextPreprocessedEntity(
GlobalSLocOffsetMapType::const_iterator SLocMapI) const;
- /// \brief Returns (ModuleFile, Local index) pair for \p GlobalIndex of a
+ /// Returns (ModuleFile, Local index) pair for \p GlobalIndex of a
/// preprocessed entity.
std::pair<ModuleFile *, unsigned>
getModulePreprocessedEntity(unsigned GlobalIndex);
- /// \brief Returns (begin, end) pair for the preprocessed entities of a
+ /// Returns (begin, end) pair for the preprocessed entities of a
/// particular module.
llvm::iterator_range<PreprocessingRecord::iterator>
getModulePreprocessedEntities(ModuleFile &Mod) const;
@@ -1416,7 +1422,7 @@ private:
PendingDeclContextInfos.push_back(Info);
}
- /// \brief Produce an error diagnostic and return true.
+ /// Produce an error diagnostic and return true.
///
/// This routine should only be used for fatal errors that have to
/// do with non-routine failures (e.g., corrupted AST file).
@@ -1425,7 +1431,7 @@ private:
StringRef Arg2 = StringRef()) const;
public:
- /// \brief Load the AST file and validate its contents against the given
+ /// Load the AST file and validate its contents against the given
/// Preprocessor.
///
/// \param PP the preprocessor associated with the context in which this
@@ -1480,34 +1486,34 @@ public:
FileManager &getFileManager() const { return FileMgr; }
DiagnosticsEngine &getDiags() const { return Diags; }
- /// \brief Flags that indicate what kind of AST loading failures the client
+ /// Flags that indicate what kind of AST loading failures the client
/// of the AST reader can directly handle.
///
/// When a client states that it can handle a particular kind of failure,
/// the AST reader will not emit errors when producing that kind of failure.
enum LoadFailureCapabilities {
- /// \brief The client can't handle any AST loading failures.
+ /// The client can't handle any AST loading failures.
ARR_None = 0,
- /// \brief The client can handle an AST file that cannot load because it
+ /// The client can handle an AST file that cannot load because it
/// is missing.
ARR_Missing = 0x1,
- /// \brief The client can handle an AST file that cannot load because it
+ /// The client can handle an AST file that cannot load because it
/// is out-of-date relative to its input files.
ARR_OutOfDate = 0x2,
- /// \brief The client can handle an AST file that cannot load because it
+ /// The client can handle an AST file that cannot load because it
/// was built with a different version of Clang.
ARR_VersionMismatch = 0x4,
- /// \brief The client can handle an AST file that cannot load because it's
+ /// The client can handle an AST file that cannot load because it's
/// compiled configuration doesn't match that of the context it was
/// loaded into.
ARR_ConfigurationMismatch = 0x8
};
- /// \brief Load the AST file designated by the given file name.
+ /// Load the AST file designated by the given file name.
///
/// \param FileName The name of the AST file to load.
///
@@ -1528,7 +1534,7 @@ public:
unsigned ClientLoadCapabilities,
SmallVectorImpl<ImportedSubmodule> *Imported = nullptr);
- /// \brief Make the entities in the given module and any of its (non-explicit)
+ /// Make the entities in the given module and any of its (non-explicit)
/// submodules visible to name lookup.
///
/// \param Mod The module whose names should be made visible.
@@ -1541,24 +1547,24 @@ public:
Module::NameVisibilityKind NameVisibility,
SourceLocation ImportLoc);
- /// \brief Make the names within this set of hidden names visible.
+ /// Make the names within this set of hidden names visible.
void makeNamesVisible(const HiddenNames &Names, Module *Owner);
- /// \brief Note that MergedDef is a redefinition of the canonical definition
+ /// Note that MergedDef is a redefinition of the canonical definition
/// Def, so Def should be visible whenever MergedDef is.
void mergeDefinitionVisibility(NamedDecl *Def, NamedDecl *MergedDef);
- /// \brief Take the AST callbacks listener.
+ /// Take the AST callbacks listener.
std::unique_ptr<ASTReaderListener> takeListener() {
return std::move(Listener);
}
- /// \brief Set the AST callbacks listener.
+ /// Set the AST callbacks listener.
void setListener(std::unique_ptr<ASTReaderListener> Listener) {
this->Listener = std::move(Listener);
}
- /// \brief Add an AST callback listener.
+ /// Add an AST callback listener.
///
/// Takes ownership of \p L.
void addListener(std::unique_ptr<ASTReaderListener> L) {
@@ -1593,67 +1599,72 @@ public:
}
};
- /// \brief Set the AST deserialization listener.
+ /// Set the AST deserialization listener.
void setDeserializationListener(ASTDeserializationListener *Listener,
bool TakeOwnership = false);
- /// \brief Determine whether this AST reader has a global index.
+ /// Get the AST deserialization listener.
+ ASTDeserializationListener *getDeserializationListener() {
+ return DeserializationListener;
+ }
+
+ /// Determine whether this AST reader has a global index.
bool hasGlobalIndex() const { return (bool)GlobalIndex; }
- /// \brief Return global module index.
+ /// Return global module index.
GlobalModuleIndex *getGlobalIndex() { return GlobalIndex.get(); }
- /// \brief Reset reader for a reload try.
+ /// Reset reader for a reload try.
void resetForReload() { TriedLoadingGlobalIndex = false; }
- /// \brief Attempts to load the global index.
+ /// Attempts to load the global index.
///
/// \returns true if loading the global index has failed for any reason.
bool loadGlobalIndex();
- /// \brief Determine whether we tried to load the global index, but failed,
+ /// Determine whether we tried to load the global index, but failed,
/// e.g., because it is out-of-date or does not exist.
bool isGlobalIndexUnavailable() const;
- /// \brief Initializes the ASTContext
+ /// Initializes the ASTContext
void InitializeContext();
- /// \brief Update the state of Sema after loading some additional modules.
+ /// Update the state of Sema after loading some additional modules.
void UpdateSema();
- /// \brief Add in-memory (virtual file) buffer.
+ /// Add in-memory (virtual file) buffer.
void addInMemoryBuffer(StringRef &FileName,
std::unique_ptr<llvm::MemoryBuffer> Buffer) {
ModuleMgr.addInMemoryBuffer(FileName, std::move(Buffer));
}
- /// \brief Finalizes the AST reader's state before writing an AST file to
+ /// Finalizes the AST reader's state before writing an AST file to
/// disk.
///
/// This operation may undo temporary state in the AST that should not be
/// emitted.
void finalizeForWriting();
- /// \brief Retrieve the module manager.
+ /// Retrieve the module manager.
ModuleManager &getModuleManager() { return ModuleMgr; }
- /// \brief Retrieve the preprocessor.
+ /// Retrieve the preprocessor.
Preprocessor &getPreprocessor() const { return PP; }
- /// \brief Retrieve the name of the original source file name for the primary
+ /// Retrieve the name of the original source file name for the primary
/// module file.
StringRef getOriginalSourceFile() {
return ModuleMgr.getPrimaryModule().OriginalSourceFileName;
}
- /// \brief Retrieve the name of the original source file name directly from
+ /// Retrieve the name of the original source file name directly from
/// the AST file, without actually loading the AST file.
static std::string
getOriginalSourceFile(const std::string &ASTFileName, FileManager &FileMgr,
const PCHContainerReader &PCHContainerRdr,
DiagnosticsEngine &Diags);
- /// \brief Read the control block for the named AST file.
+ /// Read the control block for the named AST file.
///
/// \returns true if an error occurred, false otherwise.
static bool
@@ -1663,7 +1674,7 @@ public:
ASTReaderListener &Listener,
bool ValidateDiagnosticOptions);
- /// \brief Determine whether the given AST file is acceptable to load into a
+ /// Determine whether the given AST file is acceptable to load into a
/// translation unit with the given language and target options.
static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
const PCHContainerReader &PCHContainerRdr,
@@ -1672,68 +1683,71 @@ public:
const PreprocessorOptions &PPOpts,
StringRef ExistingModuleCachePath);
- /// \brief Returns the suggested contents of the predefines buffer,
+ /// Returns the suggested contents of the predefines buffer,
/// which contains a (typically-empty) subset of the predefines
/// build prior to including the precompiled header.
const std::string &getSuggestedPredefines() { return SuggestedPredefines; }
- /// \brief Read a preallocated preprocessed entity from the external source.
+ /// Read a preallocated preprocessed entity from the external source.
///
/// \returns null if an error occurred that prevented the preprocessed
/// entity from being loaded.
PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) override;
- /// \brief Returns a pair of [Begin, End) indices of preallocated
+ /// Returns a pair of [Begin, End) indices of preallocated
/// preprocessed entities that \p Range encompasses.
std::pair<unsigned, unsigned>
findPreprocessedEntitiesInRange(SourceRange Range) override;
- /// \brief Optionally returns true or false if the preallocated preprocessed
+ /// Optionally returns true or false if the preallocated preprocessed
/// entity with index \p Index came from file \p FID.
Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
FileID FID) override;
- /// \brief Read the header file information for the given file entry.
+ /// Read a preallocated skipped range from the external source.
+ SourceRange ReadSkippedRange(unsigned Index) override;
+
+ /// Read the header file information for the given file entry.
HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) override;
void ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag);
- /// \brief Returns the number of source locations found in the chain.
+ /// Returns the number of source locations found in the chain.
unsigned getTotalNumSLocs() const {
return TotalNumSLocEntries;
}
- /// \brief Returns the number of identifiers found in the chain.
+ /// Returns the number of identifiers found in the chain.
unsigned getTotalNumIdentifiers() const {
return static_cast<unsigned>(IdentifiersLoaded.size());
}
- /// \brief Returns the number of macros found in the chain.
+ /// Returns the number of macros found in the chain.
unsigned getTotalNumMacros() const {
return static_cast<unsigned>(MacrosLoaded.size());
}
- /// \brief Returns the number of types found in the chain.
+ /// Returns the number of types found in the chain.
unsigned getTotalNumTypes() const {
return static_cast<unsigned>(TypesLoaded.size());
}
- /// \brief Returns the number of declarations found in the chain.
+ /// Returns the number of declarations found in the chain.
unsigned getTotalNumDecls() const {
return static_cast<unsigned>(DeclsLoaded.size());
}
- /// \brief Returns the number of submodules known.
+ /// Returns the number of submodules known.
unsigned getTotalNumSubmodules() const {
return static_cast<unsigned>(SubmodulesLoaded.size());
}
- /// \brief Returns the number of selectors found in the chain.
+ /// Returns the number of selectors found in the chain.
unsigned getTotalNumSelectors() const {
return static_cast<unsigned>(SelectorsLoaded.size());
}
- /// \brief Returns the number of preprocessed entities known to the AST
+ /// Returns the number of preprocessed entities known to the AST
/// reader.
unsigned getTotalNumPreprocessedEntities() const {
unsigned Result = 0;
@@ -1742,13 +1756,13 @@ public:
return Result;
}
- /// \brief Reads a TemplateArgumentLocInfo appropriate for the
+ /// Reads a TemplateArgumentLocInfo appropriate for the
/// given TemplateArgument kind.
TemplateArgumentLocInfo
GetTemplateArgumentLocInfo(ModuleFile &F, TemplateArgument::ArgKind Kind,
const RecordData &Record, unsigned &Idx);
- /// \brief Reads a TemplateArgumentLoc.
+ /// Reads a TemplateArgumentLoc.
TemplateArgumentLoc
ReadTemplateArgumentLoc(ModuleFile &F,
const RecordData &Record, unsigned &Idx);
@@ -1757,63 +1771,67 @@ public:
ReadASTTemplateArgumentListInfo(ModuleFile &F,
const RecordData &Record, unsigned &Index);
- /// \brief Reads a declarator info from the given record.
+ /// Reads a declarator info from the given record.
TypeSourceInfo *GetTypeSourceInfo(ModuleFile &F,
const RecordData &Record, unsigned &Idx);
- /// \brief Resolve a type ID into a type, potentially building a new
+ /// Raad the type locations for the given TInfo.
+ void ReadTypeLoc(ModuleFile &F, const RecordData &Record, unsigned &Idx,
+ TypeLoc TL);
+
+ /// Resolve a type ID into a type, potentially building a new
/// type.
QualType GetType(serialization::TypeID ID);
- /// \brief Resolve a local type ID within a given AST file into a type.
+ /// Resolve a local type ID within a given AST file into a type.
QualType getLocalType(ModuleFile &F, unsigned LocalID);
- /// \brief Map a local type ID within a given AST file into a global type ID.
+ /// Map a local type ID within a given AST file into a global type ID.
serialization::TypeID getGlobalTypeID(ModuleFile &F, unsigned LocalID) const;
- /// \brief Read a type from the current position in the given record, which
+ /// Read a type from the current position in the given record, which
/// was read from the given AST file.
QualType readType(ModuleFile &F, const RecordData &Record, unsigned &Idx) {
if (Idx >= Record.size())
- return QualType();
+ return {};
return getLocalType(F, Record[Idx++]);
}
- /// \brief Map from a local declaration ID within a given module to a
+ /// Map from a local declaration ID within a given module to a
/// global declaration ID.
serialization::DeclID getGlobalDeclID(ModuleFile &F,
serialization::LocalDeclID LocalID) const;
- /// \brief Returns true if global DeclID \p ID originated from module \p M.
+ /// Returns true if global DeclID \p ID originated from module \p M.
bool isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const;
- /// \brief Retrieve the module file that owns the given declaration, or NULL
+ /// Retrieve the module file that owns the given declaration, or NULL
/// if the declaration is not from a module file.
ModuleFile *getOwningModuleFile(const Decl *D);
- /// \brief Get the best name we know for the module that owns the given
+ /// Get the best name we know for the module that owns the given
/// declaration, or an empty string if the declaration is not from a module.
std::string getOwningModuleNameForDiagnostic(const Decl *D);
- /// \brief Returns the source location for the decl \p ID.
+ /// Returns the source location for the decl \p ID.
SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID);
- /// \brief Resolve a declaration ID into a declaration, potentially
+ /// Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
Decl *GetDecl(serialization::DeclID ID);
Decl *GetExternalDecl(uint32_t ID) override;
- /// \brief Resolve a declaration ID into a declaration. Return 0 if it's not
+ /// Resolve a declaration ID into a declaration. Return 0 if it's not
/// been loaded yet.
Decl *GetExistingDecl(serialization::DeclID ID);
- /// \brief Reads a declaration with the given local ID in the given module.
+ /// Reads a declaration with the given local ID in the given module.
Decl *GetLocalDecl(ModuleFile &F, uint32_t LocalID) {
return GetDecl(getGlobalDeclID(F, LocalID));
}
- /// \brief Reads a declaration with the given local ID in the given module.
+ /// Reads a declaration with the given local ID in the given module.
///
/// \returns The requested declaration, casted to the given return type.
template<typename T>
@@ -1821,7 +1839,7 @@ public:
return cast_or_null<T>(GetLocalDecl(F, LocalID));
}
- /// \brief Map a global declaration ID into the declaration ID used to
+ /// Map a global declaration ID into the declaration ID used to
/// refer to this declaration within the given module fule.
///
/// \returns the global ID of the given declaration as known in the given
@@ -1830,20 +1848,20 @@ public:
mapGlobalIDToModuleFileGlobalID(ModuleFile &M,
serialization::DeclID GlobalID);
- /// \brief Reads a declaration ID from the given position in a record in the
+ /// Reads a declaration ID from the given position in a record in the
/// given module.
///
/// \returns The declaration ID read from the record, adjusted to a global ID.
serialization::DeclID ReadDeclID(ModuleFile &F, const RecordData &Record,
unsigned &Idx);
- /// \brief Reads a declaration from the given position in a record in the
+ /// Reads a declaration from the given position in a record in the
/// given module.
Decl *ReadDecl(ModuleFile &F, const RecordData &R, unsigned &I) {
return GetDecl(ReadDeclID(F, R, I));
}
- /// \brief Reads a declaration from the given position in a record in the
+ /// Reads a declaration from the given position in a record in the
/// given module.
///
/// \returns The declaration read from this location, casted to the given
@@ -1853,14 +1871,14 @@ public:
return cast_or_null<T>(GetDecl(ReadDeclID(F, R, I)));
}
- /// \brief If any redeclarations of \p D have been imported since it was
+ /// If any redeclarations of \p D have been imported since it was
/// last checked, this digs out those redeclarations and adds them to the
/// redeclaration chain for \p D.
void CompleteRedeclChain(const Decl *D) override;
CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
- /// \brief Resolve the offset of a statement into a statement.
+ /// Resolve the offset of a statement into a statement.
///
/// This operation will read a new statement from the external
/// source each time it is called, and is meant to be used via a
@@ -1872,13 +1890,13 @@ public:
/// and then leave the cursor pointing into the block.
static bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID);
- /// \brief Finds all the visible declarations with a given name.
+ /// Finds all the visible declarations with a given name.
/// The current implementation of this method just loads the entire
/// lookup table as unmaterialized references.
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;
- /// \brief Read all of the declarations lexically stored in a
+ /// Read all of the declarations lexically stored in a
/// declaration context.
///
/// \param DC The declaration context whose declarations will be
@@ -1896,47 +1914,47 @@ public:
llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
SmallVectorImpl<Decl *> &Decls) override;
- /// \brief Get the decls that are contained in a file in the Offset/Length
+ /// 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.
void FindFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
SmallVectorImpl<Decl *> &Decls) override;
- /// \brief Notify ASTReader that we started deserialization of
+ /// Notify ASTReader 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.
void StartedDeserializing() override;
- /// \brief Notify ASTReader that we finished the deserialization of
+ /// Notify ASTReader that we finished the deserialization of
/// a decl or type. Must be paired with StartedDeserializing.
void FinishedDeserializing() override;
- /// \brief Function that will be invoked when we begin parsing a new
+ /// Function that will be invoked when we begin parsing a new
/// translation unit involving this external AST source.
///
/// This function will provide all of the external definitions to
/// the ASTConsumer.
void StartTranslationUnit(ASTConsumer *Consumer) override;
- /// \brief Print some statistics about AST usage.
+ /// Print some statistics about AST usage.
void PrintStats() override;
- /// \brief Dump information about the AST reader to standard error.
+ /// Dump information about the AST reader to standard error.
void dump();
/// Return the amount of memory used by memory buffers, breaking down
/// by heap-backed versus mmap'ed memory.
void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
- /// \brief Initialize the semantic source with the Sema instance
+ /// Initialize the semantic source with the Sema instance
/// being used to perform semantic analysis on the abstract syntax
/// tree.
void InitializeSema(Sema &S) override;
- /// \brief Inform the semantic consumer that Sema is no longer available.
+ /// Inform the semantic consumer that Sema is no longer available.
void ForgetSema() override { SemaObj = nullptr; }
- /// \brief Retrieve the IdentifierInfo for the named identifier.
+ /// Retrieve the IdentifierInfo for the named identifier.
///
/// This routine builds a new IdentifierInfo for the given identifier. If any
/// declarations with this name are visible from translation unit scope, their
@@ -1944,11 +1962,11 @@ public:
/// chain of the identifier.
IdentifierInfo *get(StringRef Name) override;
- /// \brief Retrieve an iterator into the set of all identifiers
+ /// Retrieve an iterator into the set of all identifiers
/// in all loaded AST files.
IdentifierIterator *getIdentifiers() override;
- /// \brief Load the contents of the global method pool for a given
+ /// Load the contents of the global method pool for a given
/// selector.
void ReadMethodPool(Selector Sel) override;
@@ -1956,7 +1974,7 @@ public:
/// selector if necessary.
void updateOutOfDateSelector(Selector Sel) override;
- /// \brief Load the set of namespaces that are known to the external source,
+ /// Load the set of namespaces that are known to the external source,
/// which will be used during typo correction.
void ReadKnownNamespaces(
SmallVectorImpl<NamespaceDecl *> &Namespaces) override;
@@ -1998,7 +2016,7 @@ public:
llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
&LPTMap) override;
- /// \brief Load a selector from disk, registering its ID if it exists.
+ /// Load a selector from disk, registering its ID if it exists.
void LoadSelector(Selector Sel);
void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
@@ -2006,10 +2024,10 @@ public:
const SmallVectorImpl<uint32_t> &DeclIDs,
SmallVectorImpl<Decl *> *Decls = nullptr);
- /// \brief Report a diagnostic.
+ /// Report a diagnostic.
DiagnosticBuilder Diag(unsigned DiagID) const;
- /// \brief Report a diagnostic.
+ /// Report a diagnostic.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const;
IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID);
@@ -2033,47 +2051,49 @@ public:
void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
- /// \brief Retrieve the macro with the given ID.
+ /// Retrieve the macro with the given ID.
MacroInfo *getMacro(serialization::MacroID ID);
- /// \brief Retrieve the global macro ID corresponding to the given local
+ /// Retrieve the global macro ID corresponding to the given local
/// ID within the given module file.
serialization::MacroID getGlobalMacroID(ModuleFile &M, unsigned LocalID);
- /// \brief Read the source location entry with index ID.
+ /// Read the source location entry with index ID.
bool ReadSLocEntry(int ID) override;
- /// \brief Retrieve the module import location and module name for the
+ /// Retrieve the module import location and module name for the
/// given source manager entry ID.
std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID) override;
- /// \brief Retrieve the global submodule ID given a module and its local ID
+ /// Retrieve the global submodule ID given a module and its local ID
/// number.
serialization::SubmoduleID
getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID);
- /// \brief Retrieve the submodule that corresponds to a global submodule ID.
+ /// Retrieve the submodule that corresponds to a global submodule ID.
///
Module *getSubmodule(serialization::SubmoduleID GlobalID);
- /// \brief Retrieve the module that corresponds to the given module ID.
+ /// Retrieve the module that corresponds to the given module ID.
///
/// Note: overrides method in ExternalASTSource
Module *getModule(unsigned ID) override;
- /// \brief Retrieve the module file with a given local ID within the specified
+ bool DeclIsFromPCHWithObjectFile(const Decl *D) override;
+
+ /// Retrieve the module file with a given local ID within the specified
/// ModuleFile.
ModuleFile *getLocalModuleFile(ModuleFile &M, unsigned ID);
- /// \brief Get an ID for the given module file.
+ /// Get an ID for the given module file.
unsigned getModuleFileID(ModuleFile *M);
- /// \brief Return a descriptor for the corresponding module.
+ /// Return a descriptor for the corresponding module.
llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override;
ExtKind hasExternalDefinitions(const Decl *D) override;
- /// \brief Retrieve a selector from the given module with its local ID
+ /// Retrieve a selector from the given module with its local ID
/// number.
Selector getLocalSelector(ModuleFile &M, unsigned LocalID);
@@ -2086,12 +2106,12 @@ public:
return getLocalSelector(M, Record[Idx++]);
}
- /// \brief Retrieve the global selector ID that corresponds to this
+ /// Retrieve the global selector ID that corresponds to this
/// the local selector ID in a given module.
serialization::SelectorID getGlobalSelectorID(ModuleFile &F,
unsigned LocalID) const;
- /// \brief Read a declaration name.
+ /// Read a declaration name.
DeclarationName ReadDeclarationName(ModuleFile &F,
const RecordData &Record, unsigned &Idx);
void ReadDeclarationNameLoc(ModuleFile &F,
@@ -2111,54 +2131,54 @@ public:
const RecordData &Record,
unsigned &Idx);
- /// \brief Read a template name.
+ /// Read a template name.
TemplateName ReadTemplateName(ModuleFile &F, const RecordData &Record,
unsigned &Idx);
- /// \brief Read a template argument.
+ /// Read a template argument.
TemplateArgument ReadTemplateArgument(ModuleFile &F, const RecordData &Record,
unsigned &Idx,
bool Canonicalize = false);
- /// \brief Read a template parameter list.
+ /// Read a template parameter list.
TemplateParameterList *ReadTemplateParameterList(ModuleFile &F,
const RecordData &Record,
unsigned &Idx);
- /// \brief Read a template argument array.
+ /// Read a template argument array.
void ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
ModuleFile &F, const RecordData &Record,
unsigned &Idx, bool Canonicalize = false);
- /// \brief Read a UnresolvedSet structure.
+ /// Read a UnresolvedSet structure.
void ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set,
const RecordData &Record, unsigned &Idx);
- /// \brief Read a C++ base specifier.
+ /// Read a C++ base specifier.
CXXBaseSpecifier ReadCXXBaseSpecifier(ModuleFile &F,
const RecordData &Record,unsigned &Idx);
- /// \brief Read a CXXCtorInitializer array.
+ /// Read a CXXCtorInitializer array.
CXXCtorInitializer **
ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record,
unsigned &Idx);
- /// \brief Read the contents of a CXXCtorInitializer array.
+ /// Read the contents of a CXXCtorInitializer array.
CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override;
- /// \brief Read a source location from raw form and return it in its
+ /// Read a source location from raw form and return it in its
/// originating module file's source location space.
SourceLocation ReadUntranslatedSourceLocation(uint32_t Raw) const {
return SourceLocation::getFromRawEncoding((Raw >> 1) | (Raw << 31));
}
- /// \brief Read a source location from raw form.
+ /// Read a source location from raw form.
SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, uint32_t Raw) const {
SourceLocation Loc = ReadUntranslatedSourceLocation(Raw);
return TranslateSourceLocation(ModuleFile, Loc);
}
- /// \brief Translate a source location from another module file's source
+ /// Translate a source location from another module file's source
/// location space into ours.
SourceLocation TranslateSourceLocation(ModuleFile &ModuleFile,
SourceLocation Loc) const {
@@ -2171,59 +2191,59 @@ public:
return Loc.getLocWithOffset(Remap);
}
- /// \brief Read a source location.
+ /// Read a source location.
SourceLocation ReadSourceLocation(ModuleFile &ModuleFile,
const RecordDataImpl &Record,
unsigned &Idx) {
return ReadSourceLocation(ModuleFile, Record[Idx++]);
}
- /// \brief Read a source range.
+ /// Read a source range.
SourceRange ReadSourceRange(ModuleFile &F,
const RecordData &Record, unsigned &Idx);
- /// \brief Read an integral value
+ /// Read an integral value
llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);
- /// \brief Read a signed integral value
+ /// Read a signed integral value
llvm::APSInt ReadAPSInt(const RecordData &Record, unsigned &Idx);
- /// \brief Read a floating-point value
+ /// Read a floating-point value
llvm::APFloat ReadAPFloat(const RecordData &Record,
const llvm::fltSemantics &Sem, unsigned &Idx);
- // \brief Read a string
+ // Read a string
static std::string ReadString(const RecordData &Record, unsigned &Idx);
- // \brief Skip a string
+ // Skip a string
static void SkipString(const RecordData &Record, unsigned &Idx) {
Idx += Record[Idx] + 1;
}
- // \brief Read a path
+ // Read a path
std::string ReadPath(ModuleFile &F, const RecordData &Record, unsigned &Idx);
- // \brief Skip a path
+ // Skip a path
static void SkipPath(const RecordData &Record, unsigned &Idx) {
SkipString(Record, Idx);
}
- /// \brief Read a version tuple.
+ /// Read a version tuple.
static VersionTuple ReadVersionTuple(const RecordData &Record, unsigned &Idx);
CXXTemporary *ReadCXXTemporary(ModuleFile &F, const RecordData &Record,
unsigned &Idx);
- /// \brief Reads attributes from the current stream position.
+ /// Reads attributes from the current stream position.
void ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs);
- /// \brief Reads a statement.
+ /// Reads a statement.
Stmt *ReadStmt(ModuleFile &F);
- /// \brief Reads an expression.
+ /// Reads an expression.
Expr *ReadExpr(ModuleFile &F);
- /// \brief Reads a sub-statement operand during statement reading.
+ /// Reads a sub-statement operand during statement reading.
Stmt *ReadSubStmt() {
assert(ReadingKind == Read_Stmt &&
"Should be called only during statement reading!");
@@ -2233,21 +2253,21 @@ public:
return StmtStack.pop_back_val();
}
- /// \brief Reads a sub-expression operand during statement reading.
+ /// Reads a sub-expression operand during statement reading.
Expr *ReadSubExpr();
- /// \brief Reads a token out of a record.
+ /// Reads a token out of a record.
Token ReadToken(ModuleFile &M, const RecordDataImpl &Record, unsigned &Idx);
- /// \brief Reads the macro record located at the given offset.
+ /// Reads the macro record located at the given offset.
MacroInfo *ReadMacroRecord(ModuleFile &F, uint64_t Offset);
- /// \brief Determine the global preprocessed entity ID that corresponds to
+ /// Determine the global preprocessed entity ID that corresponds to
/// the given local ID within the given module.
serialization::PreprocessedEntityID
getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const;
- /// \brief Add a macro to deserialize its macro directive history.
+ /// Add a macro to deserialize its macro directive history.
///
/// \param II The name of the macro.
/// \param M The module file.
@@ -2256,56 +2276,56 @@ public:
void addPendingMacro(IdentifierInfo *II, ModuleFile *M,
uint64_t MacroDirectivesOffset);
- /// \brief Read the set of macros defined by this external macro source.
+ /// Read the set of macros defined by this external macro source.
void ReadDefinedMacros() override;
- /// \brief Update an out-of-date identifier.
+ /// Update an out-of-date identifier.
void updateOutOfDateIdentifier(IdentifierInfo &II) override;
- /// \brief Note that this identifier is up-to-date.
+ /// Note that this identifier is up-to-date.
void markIdentifierUpToDate(IdentifierInfo *II);
- /// \brief Load all external visible decls in the given DeclContext.
+ /// Load all external visible decls in the given DeclContext.
void completeVisibleDeclsMap(const DeclContext *DC) override;
- /// \brief Retrieve the AST context that this AST reader supplements.
+ /// Retrieve the AST context that this AST reader supplements.
ASTContext &getContext() {
assert(ContextObj && "requested AST context when not loading AST");
return *ContextObj;
}
- // \brief Contains the IDs for declarations that were requested before we have
+ // Contains the IDs for declarations that were requested before we have
// access to a Sema object.
SmallVector<uint64_t, 16> PreloadedDeclIDs;
- /// \brief Retrieve the semantic analysis object used to analyze the
+ /// Retrieve the semantic analysis object used to analyze the
/// translation unit in which the precompiled header is being
/// imported.
Sema *getSema() { return SemaObj; }
- /// \brief Get the identifier resolver used for name lookup / updates
+ /// Get the identifier resolver used for name lookup / updates
/// in the translation unit scope. We have one of these even if we don't
/// have a Sema object.
IdentifierResolver &getIdResolver();
- /// \brief Retrieve the identifier table associated with the
+ /// Retrieve the identifier table associated with the
/// preprocessor.
IdentifierTable &getIdentifierTable();
- /// \brief Record that the given ID maps to the given switch-case
+ /// Record that the given ID maps to the given switch-case
/// statement.
void RecordSwitchCaseID(SwitchCase *SC, unsigned ID);
- /// \brief Retrieve the switch-case statement with the given ID.
+ /// Retrieve the switch-case statement with the given ID.
SwitchCase *getSwitchCaseWithID(unsigned ID);
void ClearSwitchCaseIDs();
- /// \brief Cursors for comments blocks.
+ /// Cursors for comments blocks.
SmallVector<std::pair<llvm::BitstreamCursor,
serialization::ModuleFile *>, 8> CommentsCursors;
- /// \brief Loads comments ranges.
+ /// Loads comments ranges.
void ReadComments() override;
/// Visit all the input files of the given module file.
@@ -2323,7 +2343,7 @@ public:
bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
};
-/// \brief An object for streaming information from a record.
+/// An object for streaming information from a record.
class ASTRecordReader {
using ModuleFile = serialization::ModuleFile;
@@ -2339,56 +2359,56 @@ public:
/// Construct an ASTRecordReader that uses the default encoding scheme.
ASTRecordReader(ASTReader &Reader, ModuleFile &F) : Reader(&Reader), F(&F) {}
- /// \brief Reads a record with id AbbrevID from Cursor, resetting the
+ /// Reads a record with id AbbrevID from Cursor, resetting the
/// internal state.
unsigned readRecord(llvm::BitstreamCursor &Cursor, unsigned AbbrevID);
- /// \brief Is this a module file for a module (rather than a PCH or similar).
+ /// Is this a module file for a module (rather than a PCH or similar).
bool isModule() const { return F->isModule(); }
- /// \brief Retrieve the AST context that this AST reader supplements.
+ /// Retrieve the AST context that this AST reader supplements.
ASTContext &getContext() { return Reader->getContext(); }
- /// \brief The current position in this record.
+ /// The current position in this record.
unsigned getIdx() const { return Idx; }
- /// \brief The length of this record.
+ /// The length of this record.
size_t size() const { return Record.size(); }
- /// \brief An arbitrary index in this record.
+ /// An arbitrary index in this record.
const uint64_t &operator[](size_t N) { return Record[N]; }
- /// \brief The last element in this record.
+ /// The last element in this record.
const uint64_t &back() const { return Record.back(); }
- /// \brief Returns the current value in this record, and advances to the
+ /// Returns the current value in this record, and advances to the
/// next value.
const uint64_t &readInt() { return Record[Idx++]; }
- /// \brief Returns the current value in this record, without advancing.
+ /// Returns the current value in this record, without advancing.
const uint64_t &peekInt() { return Record[Idx]; }
- /// \brief Skips the specified number of values.
+ /// Skips the specified number of values.
void skipInts(unsigned N) { Idx += N; }
- /// \brief Retrieve the global submodule ID its local ID number.
+ /// Retrieve the global submodule ID its local ID number.
serialization::SubmoduleID
getGlobalSubmoduleID(unsigned LocalID) {
return Reader->getGlobalSubmoduleID(*F, LocalID);
}
- /// \brief Retrieve the submodule that corresponds to a global submodule ID.
+ /// Retrieve the submodule that corresponds to a global submodule ID.
Module *getSubmodule(serialization::SubmoduleID GlobalID) {
return Reader->getSubmodule(GlobalID);
}
- /// \brief Read the record that describes the lexical contents of a DC.
+ /// Read the record that describes the lexical contents of a DC.
bool readLexicalDeclContextStorage(uint64_t Offset, DeclContext *DC) {
return Reader->ReadLexicalDeclContextStorage(*F, F->DeclsCursor, Offset,
DC);
}
- /// \brief Read the record that describes the visible contents of a DC.
+ /// Read the record that describes the visible contents of a DC.
bool readVisibleDeclContextStorage(uint64_t Offset,
serialization::DeclID ID) {
return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset,
@@ -2400,24 +2420,24 @@ public:
return Reader->readExceptionSpec(*F, ExceptionStorage, ESI, Record, Idx);
}
- /// \brief Get the global offset corresponding to a local offset.
+ /// Get the global offset corresponding to a local offset.
uint64_t getGlobalBitOffset(uint32_t LocalOffset) {
return Reader->getGlobalBitOffset(*F, LocalOffset);
}
- /// \brief Reads a statement.
+ /// Reads a statement.
Stmt *readStmt() { return Reader->ReadStmt(*F); }
- /// \brief Reads an expression.
+ /// Reads an expression.
Expr *readExpr() { return Reader->ReadExpr(*F); }
- /// \brief Reads a sub-statement operand during statement reading.
+ /// Reads a sub-statement operand during statement reading.
Stmt *readSubStmt() { return Reader->ReadSubStmt(); }
- /// \brief Reads a sub-expression operand during statement reading.
+ /// Reads a sub-expression operand during statement reading.
Expr *readSubExpr() { return Reader->ReadSubExpr(); }
- /// \brief Reads a declaration with the given local ID in the given module.
+ /// Reads a declaration with the given local ID in the given module.
///
/// \returns The requested declaration, casted to the given return type.
template<typename T>
@@ -2425,14 +2445,14 @@ public:
return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID));
}
- /// \brief Reads a TemplateArgumentLocInfo appropriate for the
+ /// Reads a TemplateArgumentLocInfo appropriate for the
/// given TemplateArgument kind, advancing Idx.
TemplateArgumentLocInfo
getTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind) {
return Reader->GetTemplateArgumentLocInfo(*F, Kind, Record, Idx);
}
- /// \brief Reads a TemplateArgumentLoc, advancing Idx.
+ /// Reads a TemplateArgumentLoc, advancing Idx.
TemplateArgumentLoc
readTemplateArgumentLoc() {
return Reader->ReadTemplateArgumentLoc(*F, Record, Idx);
@@ -2443,35 +2463,40 @@ public:
return Reader->ReadASTTemplateArgumentListInfo(*F, Record, Idx);
}
- /// \brief Reads a declarator info from the given record, advancing Idx.
+ /// Reads a declarator info from the given record, advancing Idx.
TypeSourceInfo *getTypeSourceInfo() {
return Reader->GetTypeSourceInfo(*F, Record, Idx);
}
- /// \brief Map a local type ID within a given AST file to a global type ID.
+ /// Reads the location information for a type.
+ void readTypeLoc(TypeLoc TL) {
+ return Reader->ReadTypeLoc(*F, Record, Idx, TL);
+ }
+
+ /// Map a local type ID within a given AST file to a global type ID.
serialization::TypeID getGlobalTypeID(unsigned LocalID) const {
return Reader->getGlobalTypeID(*F, LocalID);
}
- /// \brief Read a type from the current position in the record.
+ /// Read a type from the current position in the record.
QualType readType() {
return Reader->readType(*F, Record, Idx);
}
- /// \brief Reads a declaration ID from the given position in this record.
+ /// Reads a declaration ID from the given position in this record.
///
/// \returns The declaration ID read from the record, adjusted to a global ID.
serialization::DeclID readDeclID() {
return Reader->ReadDeclID(*F, Record, Idx);
}
- /// \brief Reads a declaration from the given position in a record in the
+ /// Reads a declaration from the given position in a record in the
/// given module, advancing Idx.
Decl *readDecl() {
return Reader->ReadDecl(*F, Record, Idx);
}
- /// \brief Reads a declaration from the given position in the record,
+ /// Reads a declaration from the given position in the record,
/// advancing Idx.
///
/// \returns The declaration read from this location, casted to the given
@@ -2485,12 +2510,12 @@ public:
return Reader->GetIdentifierInfo(*F, Record, Idx);
}
- /// \brief Read a selector from the Record, advancing Idx.
+ /// Read a selector from the Record, advancing Idx.
Selector readSelector() {
return Reader->ReadSelector(*F, Record, Idx);
}
- /// \brief Read a declaration name, advancing Idx.
+ /// Read a declaration name, advancing Idx.
DeclarationName readDeclarationName() {
return Reader->ReadDeclarationName(*F, Record, Idx);
}
@@ -2513,39 +2538,39 @@ public:
return Reader->ReadNestedNameSpecifierLoc(*F, Record, Idx);
}
- /// \brief Read a template name, advancing Idx.
+ /// Read a template name, advancing Idx.
TemplateName readTemplateName() {
return Reader->ReadTemplateName(*F, Record, Idx);
}
- /// \brief Read a template argument, advancing Idx.
+ /// Read a template argument, advancing Idx.
TemplateArgument readTemplateArgument(bool Canonicalize = false) {
return Reader->ReadTemplateArgument(*F, Record, Idx, Canonicalize);
}
- /// \brief Read a template parameter list, advancing Idx.
+ /// Read a template parameter list, advancing Idx.
TemplateParameterList *readTemplateParameterList() {
return Reader->ReadTemplateParameterList(*F, Record, Idx);
}
- /// \brief Read a template argument array, advancing Idx.
+ /// Read a template argument array, advancing Idx.
void readTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
bool Canonicalize = false) {
return Reader->ReadTemplateArgumentList(TemplArgs, *F, Record, Idx,
Canonicalize);
}
- /// \brief Read a UnresolvedSet structure, advancing Idx.
+ /// Read a UnresolvedSet structure, advancing Idx.
void readUnresolvedSet(LazyASTUnresolvedSet &Set) {
return Reader->ReadUnresolvedSet(*F, Set, Record, Idx);
}
- /// \brief Read a C++ base specifier, advancing Idx.
+ /// Read a C++ base specifier, advancing Idx.
CXXBaseSpecifier readCXXBaseSpecifier() {
return Reader->ReadCXXBaseSpecifier(*F, Record, Idx);
}
- /// \brief Read a CXXCtorInitializer array, advancing Idx.
+ /// Read a CXXCtorInitializer array, advancing Idx.
CXXCtorInitializer **readCXXCtorInitializers() {
return Reader->ReadCXXCtorInitializers(*F, Record, Idx);
}
@@ -2554,52 +2579,52 @@ public:
return Reader->ReadCXXTemporary(*F, Record, Idx);
}
- /// \brief Read a source location, advancing Idx.
+ /// Read a source location, advancing Idx.
SourceLocation readSourceLocation() {
return Reader->ReadSourceLocation(*F, Record, Idx);
}
- /// \brief Read a source range, advancing Idx.
+ /// Read a source range, advancing Idx.
SourceRange readSourceRange() {
return Reader->ReadSourceRange(*F, Record, Idx);
}
- /// \brief Read an integral value, advancing Idx.
+ /// Read an integral value, advancing Idx.
llvm::APInt readAPInt() {
return Reader->ReadAPInt(Record, Idx);
}
- /// \brief Read a signed integral value, advancing Idx.
+ /// Read a signed integral value, advancing Idx.
llvm::APSInt readAPSInt() {
return Reader->ReadAPSInt(Record, Idx);
}
- /// \brief Read a floating-point value, advancing Idx.
+ /// Read a floating-point value, advancing Idx.
llvm::APFloat readAPFloat(const llvm::fltSemantics &Sem) {
return Reader->ReadAPFloat(Record, Sem,Idx);
}
- /// \brief Read a string, advancing Idx.
+ /// Read a string, advancing Idx.
std::string readString() {
return Reader->ReadString(Record, Idx);
}
- /// \brief Read a path, advancing Idx.
+ /// Read a path, advancing Idx.
std::string readPath() {
return Reader->ReadPath(*F, Record, Idx);
}
- /// \brief Read a version tuple, advancing Idx.
+ /// Read a version tuple, advancing Idx.
VersionTuple readVersionTuple() {
return ASTReader::ReadVersionTuple(Record, Idx);
}
- /// \brief Reads attributes from the current stream position, advancing Idx.
+ /// Reads attributes from the current stream position, advancing Idx.
void readAttributes(AttrVec &Attrs) {
return Reader->ReadAttributes(*this, Attrs);
}
- /// \brief Reads a token out of a record, advancing Idx.
+ /// Reads a token out of a record, advancing Idx.
Token readToken() {
return Reader->ReadToken(*F, Record, Idx);
}
@@ -2608,17 +2633,17 @@ public:
Reader->RecordSwitchCaseID(SC, ID);
}
- /// \brief Retrieve the switch-case statement with the given ID.
+ /// Retrieve the switch-case statement with the given ID.
SwitchCase *getSwitchCaseWithID(unsigned ID) {
return Reader->getSwitchCaseWithID(ID);
}
};
-/// \brief Helper class that saves the current stream position and
+/// Helper class that saves the current stream position and
/// then restores it when destroyed.
struct SavedStreamPosition {
explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
- : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {}
+ : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {}
~SavedStreamPosition() {
Cursor.JumpToBit(Offset);
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 9437bf7f2c9f1..a93579930ff52 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -93,9 +93,8 @@ class SwitchCase;
class TemplateParameterList;
class Token;
class TypeSourceInfo;
-class VersionTuple;
-/// \brief Writes an AST file containing the contents of a translation unit.
+/// Writes an AST file containing the contents of a translation unit.
///
/// The ASTWriter class produces a bitstream containing the serialized
/// representation of a given abstract syntax tree and its supporting
@@ -114,7 +113,7 @@ public:
using RecordDataRef = ArrayRef<uint64_t>;
private:
- /// \brief Map that provides the ID numbers of each type within the
+ /// Map that provides the ID numbers of each type within the
/// output stream, plus those deserialized from a chained PCH.
///
/// The ID numbers of types are consecutive (in order of discovery)
@@ -126,52 +125,52 @@ private:
using TypeIdxMap = llvm::DenseMap<QualType, serialization::TypeIdx,
serialization::UnsafeQualTypeDenseMapInfo>;
- /// \brief The bitstream writer used to emit this precompiled header.
+ /// The bitstream writer used to emit this precompiled header.
llvm::BitstreamWriter &Stream;
/// The buffer associated with the bitstream.
const SmallVectorImpl<char> &Buffer;
- /// \brief The PCM manager which manages memory buffers for pcm files.
+ /// The PCM manager which manages memory buffers for pcm files.
MemoryBufferCache &PCMCache;
- /// \brief The ASTContext we're writing.
+ /// The ASTContext we're writing.
ASTContext *Context = nullptr;
- /// \brief The preprocessor we're writing.
+ /// The preprocessor we're writing.
Preprocessor *PP = nullptr;
- /// \brief The reader of existing AST files, if we're chaining.
+ /// The reader of existing AST files, if we're chaining.
ASTReader *Chain = nullptr;
- /// \brief The module we're currently writing, if any.
+ /// The module we're currently writing, if any.
Module *WritingModule = nullptr;
- /// \brief The base directory for any relative paths we emit.
+ /// The base directory for any relative paths we emit.
std::string BaseDirectory;
- /// \brief Indicates whether timestamps should be written to the produced
+ /// Indicates whether timestamps should be written to the produced
/// module file. This is the case for files implicitly written to the
/// module cache, where we need the timestamps to determine if the module
/// file is up to date, but not otherwise.
bool IncludeTimestamps;
- /// \brief Indicates when the AST writing is actively performing
+ /// Indicates when the AST writing is actively performing
/// serialization, rather than just queueing updates.
bool WritingAST = false;
- /// \brief Indicates that we are done serializing the collection of decls
+ /// Indicates that we are done serializing the collection of decls
/// and types to emit.
bool DoneWritingDeclsAndTypes = false;
- /// \brief Indicates that the AST contained compiler errors.
+ /// Indicates that the AST contained compiler errors.
bool ASTHasCompilerErrors = false;
- /// \brief Mapping from input file entries to the index into the
+ /// Mapping from input file entries to the index into the
/// offset table where information about that input file is stored.
llvm::DenseMap<const FileEntry *, uint32_t> InputFileIDs;
- /// \brief Stores a declaration or a type to be written to the AST file.
+ /// Stores a declaration or a type to be written to the AST file.
class DeclOrType {
public:
DeclOrType(Decl *D) : Stored(D), IsType(false) {}
@@ -195,16 +194,16 @@ private:
bool IsType;
};
- /// \brief The declarations and types to emit.
+ /// The declarations and types to emit.
std::queue<DeclOrType> DeclTypesToEmit;
- /// \brief The first ID number we can use for our own declarations.
+ /// The first ID number we can use for our own declarations.
serialization::DeclID FirstDeclID = serialization::NUM_PREDEF_DECL_IDS;
- /// \brief The decl ID that will be assigned to the next new decl.
+ /// The decl ID that will be assigned to the next new decl.
serialization::DeclID NextDeclID = FirstDeclID;
- /// \brief Map that provides the ID numbers of each declaration within
+ /// Map that provides the ID numbers of each declaration within
/// the output stream, as well as those deserialized from a chained PCH.
///
/// The ID numbers of declarations are consecutive (in order of
@@ -212,35 +211,35 @@ private:
/// unit, while 0 is reserved for NULL.
llvm::DenseMap<const Decl *, serialization::DeclID> DeclIDs;
- /// \brief Offset of each declaration in the bitstream, indexed by
+ /// Offset of each declaration in the bitstream, indexed by
/// the declaration's ID.
std::vector<serialization::DeclOffset> DeclOffsets;
- /// \brief Sorted (by file offset) vector of pairs of file offset/DeclID.
+ /// Sorted (by file offset) vector of pairs of file offset/DeclID.
using LocDeclIDsTy =
SmallVector<std::pair<unsigned, serialization::DeclID>, 64>;
struct DeclIDInFileInfo {
LocDeclIDsTy DeclIDs;
- /// \brief Set when the DeclIDs vectors from all files are joined, this
+ /// Set when the DeclIDs vectors from all files are joined, this
/// indicates the index that this particular vector has in the global one.
unsigned FirstDeclIndex;
};
using FileDeclIDsTy = llvm::DenseMap<FileID, DeclIDInFileInfo *>;
- /// \brief Map from file SLocEntries to info about the file-level declarations
+ /// Map from file SLocEntries to info about the file-level declarations
/// that it contains.
FileDeclIDsTy FileDeclIDs;
void associateDeclWithFile(const Decl *D, serialization::DeclID);
- /// \brief The first ID number we can use for our own types.
+ /// The first ID number we can use for our own types.
serialization::TypeID FirstTypeID = serialization::NUM_PREDEF_TYPE_IDS;
- /// \brief The type ID that will be assigned to the next new type.
+ /// The type ID that will be assigned to the next new type.
serialization::TypeID NextTypeID = FirstTypeID;
- /// \brief Map that provides the ID numbers of each type within the
+ /// Map that provides the ID numbers of each type within the
/// output stream, plus those deserialized from a chained PCH.
///
/// The ID numbers of types are consecutive (in order of discovery)
@@ -251,17 +250,17 @@ private:
/// Keys in the map never have const/volatile qualifiers.
TypeIdxMap TypeIdxs;
- /// \brief Offset of each type in the bitstream, indexed by
+ /// Offset of each type in the bitstream, indexed by
/// the type's ID.
std::vector<uint32_t> TypeOffsets;
- /// \brief The first ID number we can use for our own identifiers.
+ /// The first ID number we can use for our own identifiers.
serialization::IdentID FirstIdentID = serialization::NUM_PREDEF_IDENT_IDS;
- /// \brief The identifier ID that will be assigned to the next new identifier.
+ /// The identifier ID that will be assigned to the next new identifier.
serialization::IdentID NextIdentID = FirstIdentID;
- /// \brief Map that provides the ID numbers of each identifier in
+ /// Map that provides the ID numbers of each identifier in
/// the output stream.
///
/// The ID numbers for identifiers are consecutive (in order of
@@ -269,13 +268,13 @@ private:
/// IdentifierInfo.
llvm::MapVector<const IdentifierInfo *, serialization::IdentID> IdentifierIDs;
- /// \brief The first ID number we can use for our own macros.
+ /// The first ID number we can use for our own macros.
serialization::MacroID FirstMacroID = serialization::NUM_PREDEF_MACRO_IDS;
- /// \brief The identifier ID that will be assigned to the next new identifier.
+ /// The identifier ID that will be assigned to the next new identifier.
serialization::MacroID NextMacroID = FirstMacroID;
- /// \brief Map that provides the ID numbers of each macro.
+ /// Map that provides the ID numbers of each macro.
llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs;
struct MacroInfoToEmitData {
@@ -284,7 +283,7 @@ private:
serialization::MacroID ID;
};
- /// \brief The macro infos to emit.
+ /// The macro infos to emit.
std::vector<MacroInfoToEmitData> MacroInfosToEmit;
llvm::DenseMap<const IdentifierInfo *, uint64_t> IdentMacroDirectivesOffsetMap;
@@ -292,46 +291,46 @@ private:
/// @name FlushStmt Caches
/// @{
- /// \brief Set of parent Stmts for the currently serializing sub-stmt.
+ /// Set of parent Stmts for the currently serializing sub-stmt.
llvm::DenseSet<Stmt *> ParentStmts;
- /// \brief Offsets of sub-stmts already serialized. The offset points
+ /// Offsets of sub-stmts already serialized. The offset points
/// just after the stmt record.
llvm::DenseMap<Stmt *, uint64_t> SubStmtEntries;
/// @}
- /// \brief Offsets of each of the identifier IDs into the identifier
+ /// Offsets of each of the identifier IDs into the identifier
/// table.
std::vector<uint32_t> IdentifierOffsets;
- /// \brief The first ID number we can use for our own submodules.
+ /// The first ID number we can use for our own submodules.
serialization::SubmoduleID FirstSubmoduleID =
serialization::NUM_PREDEF_SUBMODULE_IDS;
- /// \brief The submodule ID that will be assigned to the next new submodule.
+ /// The submodule ID that will be assigned to the next new submodule.
serialization::SubmoduleID NextSubmoduleID = FirstSubmoduleID;
- /// \brief The first ID number we can use for our own selectors.
+ /// The first ID number we can use for our own selectors.
serialization::SelectorID FirstSelectorID =
serialization::NUM_PREDEF_SELECTOR_IDS;
- /// \brief The selector ID that will be assigned to the next new selector.
+ /// The selector ID that will be assigned to the next new selector.
serialization::SelectorID NextSelectorID = FirstSelectorID;
- /// \brief Map that provides the ID numbers of each Selector.
+ /// Map that provides the ID numbers of each Selector.
llvm::MapVector<Selector, serialization::SelectorID> SelectorIDs;
- /// \brief Offset of each selector within the method pool/selector
+ /// Offset of each selector within the method pool/selector
/// table, indexed by the Selector ID (-1).
std::vector<uint32_t> SelectorOffsets;
- /// \brief Mapping from macro definitions (as they occur in the preprocessing
+ /// Mapping from macro definitions (as they occur in the preprocessing
/// record) to the macro IDs.
llvm::DenseMap<const MacroDefinitionRecord *,
serialization::PreprocessedEntityID> MacroDefinitions;
- /// \brief Cache of indices of anonymous declarations within their lexical
+ /// Cache of indices of anonymous declarations within their lexical
/// contexts.
llvm::DenseMap<const Decl *, unsigned> AnonymousDeclarationNumbers;
@@ -376,17 +375,17 @@ private:
using UpdateRecord = SmallVector<DeclUpdate, 1>;
using DeclUpdateMap = llvm::MapVector<const Decl *, UpdateRecord>;
- /// \brief Mapping from declarations that came from a chained PCH to the
+ /// Mapping from declarations that came from a chained PCH to the
/// record containing modifications to them.
DeclUpdateMap DeclUpdates;
using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>;
- /// \brief Map of first declarations from a chained PCH that point to the
+ /// Map of first declarations from a chained PCH that point to the
/// most recent declarations in another PCH.
FirstLatestDeclMap FirstLatestDecls;
- /// \brief Declarations encountered that might be external
+ /// Declarations encountered that might be external
/// definitions.
///
/// We keep track of external definitions and other 'interesting' declarations
@@ -400,7 +399,7 @@ private:
SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
SmallVector<uint64_t, 16> ModularCodegenDecls;
- /// \brief DeclContexts that have received extensions since their serialized
+ /// DeclContexts that have received extensions since their serialized
/// form.
///
/// For namespaces, when we're chaining and encountering a namespace, we check
@@ -409,52 +408,52 @@ private:
/// it.
llvm::SmallSetVector<const DeclContext *, 16> UpdatedDeclContexts;
- /// \brief Keeps track of declarations that we must emit, even though we're
+ /// Keeps track of declarations that we must emit, even though we're
/// not guaranteed to be able to find them by walking the AST starting at the
/// translation unit.
SmallVector<const Decl *, 16> DeclsToEmitEvenIfUnreferenced;
- /// \brief The set of Objective-C class that have categories we
+ /// The set of Objective-C class that have categories we
/// should serialize.
llvm::SetVector<ObjCInterfaceDecl *> ObjCClassesWithCategories;
- /// \brief The set of declarations that may have redeclaration chains that
+ /// The set of declarations that may have redeclaration chains that
/// need to be serialized.
llvm::SmallVector<const Decl *, 16> Redeclarations;
- /// \brief A cache of the first local declaration for "interesting"
+ /// A cache of the first local declaration for "interesting"
/// redeclaration chains.
llvm::DenseMap<const Decl *, const Decl *> FirstLocalDeclCache;
- /// \brief Mapping from SwitchCase statements to IDs.
+ /// Mapping from SwitchCase statements to IDs.
llvm::DenseMap<SwitchCase *, unsigned> SwitchCaseIDs;
- /// \brief The number of statements written to the AST file.
+ /// The number of statements written to the AST file.
unsigned NumStatements = 0;
- /// \brief The number of macros written to the AST file.
+ /// The number of macros written to the AST file.
unsigned NumMacros = 0;
- /// \brief The number of lexical declcontexts written to the AST
+ /// The number of lexical declcontexts written to the AST
/// file.
unsigned NumLexicalDeclContexts = 0;
- /// \brief The number of visible declcontexts written to the AST
+ /// The number of visible declcontexts written to the AST
/// file.
unsigned NumVisibleDeclContexts = 0;
- /// \brief A mapping from each known submodule to its ID number, which will
+ /// A mapping from each known submodule to its ID number, which will
/// be a positive integer.
llvm::DenseMap<Module *, unsigned> SubmoduleIDs;
- /// \brief A list of the module file extension writers.
+ /// A list of the module file extension writers.
std::vector<std::unique_ptr<ModuleFileExtensionWriter>>
ModuleFileExtensionWriters;
- /// \brief Retrieve or create a submodule ID for this module.
+ /// Retrieve or create a submodule ID for this module.
unsigned getSubmoduleID(Module *Mod);
- /// \brief Write the given subexpression to the bitstream.
+ /// Write the given subexpression to the bitstream.
void WriteSubStmt(Stmt *S);
void WriteBlockInfoBlock();
@@ -540,7 +539,7 @@ private:
Module *WritingModule);
public:
- /// \brief Create a new precompiled header writer that outputs to
+ /// Create a new precompiled header writer that outputs to
/// the given bitstream.
ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
MemoryBufferCache &PCMCache,
@@ -550,12 +549,12 @@ public:
const LangOptions &getLangOpts() const;
- /// \brief Get a timestamp for output into the AST file. The actual timestamp
+ /// Get a timestamp for output into the AST file. The actual timestamp
/// of the specified file may be ignored if we have been instructed to not
/// include timestamps in the output file.
time_t getTimestampForOutput(const FileEntry *E) const;
- /// \brief Write a precompiled header for the given semantic analysis.
+ /// Write a precompiled header for the given semantic analysis.
///
/// \param SemaRef a reference to the semantic analysis object that processed
/// the AST to be written into the precompiled header.
@@ -573,46 +572,46 @@ public:
Module *WritingModule, StringRef isysroot,
bool hasErrors = false);
- /// \brief Emit a token.
+ /// Emit a token.
void AddToken(const Token &Tok, RecordDataImpl &Record);
- /// \brief Emit a source location.
+ /// Emit a source location.
void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record);
- /// \brief Emit a source range.
+ /// Emit a source range.
void AddSourceRange(SourceRange Range, RecordDataImpl &Record);
- /// \brief Emit a reference to an identifier.
+ /// Emit a reference to an identifier.
void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record);
- /// \brief Get the unique number used to refer to the given selector.
+ /// Get the unique number used to refer to the given selector.
serialization::SelectorID getSelectorRef(Selector Sel);
- /// \brief Get the unique number used to refer to the given identifier.
+ /// Get the unique number used to refer to the given identifier.
serialization::IdentID getIdentifierRef(const IdentifierInfo *II);
- /// \brief Get the unique number used to refer to the given macro.
+ /// Get the unique number used to refer to the given macro.
serialization::MacroID getMacroRef(MacroInfo *MI, const IdentifierInfo *Name);
- /// \brief Determine the ID of an already-emitted macro.
+ /// Determine the ID of an already-emitted macro.
serialization::MacroID getMacroID(MacroInfo *MI);
uint64_t getMacroDirectivesOffset(const IdentifierInfo *Name);
- /// \brief Emit a reference to a type.
+ /// Emit a reference to a type.
void AddTypeRef(QualType T, RecordDataImpl &Record);
- /// \brief Force a type to be emitted and get its ID.
+ /// Force a type to be emitted and get its ID.
serialization::TypeID GetOrCreateTypeID(QualType T);
- /// \brief Determine the type ID of an already-emitted type.
+ /// Determine the type ID of an already-emitted type.
serialization::TypeID getTypeID(QualType T) const;
- /// \brief Find the first local declaration of a given local redeclarable
+ /// Find the first local declaration of a given local redeclarable
/// decl.
const Decl *getFirstLocalDecl(const Decl *D);
- /// \brief Is this a local declaration (that is, one that will be written to
+ /// Is this a local declaration (that is, one that will be written to
/// our AST file)? This is the case for declarations that are neither imported
/// from another AST file nor predefined.
bool IsLocalDecl(const Decl *D) {
@@ -623,52 +622,52 @@ public:
I->second >= serialization::NUM_PREDEF_DECL_IDS);
};
- /// \brief Emit a reference to a declaration.
+ /// Emit a reference to a declaration.
void AddDeclRef(const Decl *D, RecordDataImpl &Record);
- /// \brief Force a declaration to be emitted and get its ID.
+ /// Force a declaration to be emitted and get its ID.
serialization::DeclID GetDeclRef(const Decl *D);
- /// \brief Determine the declaration ID of an already-emitted
+ /// Determine the declaration ID of an already-emitted
/// declaration.
serialization::DeclID getDeclID(const Decl *D);
unsigned getAnonymousDeclarationNumber(const NamedDecl *D);
- /// \brief Add a string to the given record.
+ /// Add a string to the given record.
void AddString(StringRef Str, RecordDataImpl &Record);
- /// \brief Convert a path from this build process into one that is appropriate
+ /// Convert a path from this build process into one that is appropriate
/// for emission in the module file.
bool PreparePathForOutput(SmallVectorImpl<char> &Path);
- /// \brief Add a path to the given record.
+ /// Add a path to the given record.
void AddPath(StringRef Path, RecordDataImpl &Record);
- /// \brief Emit the current record with the given path as a blob.
+ /// Emit the current record with the given path as a blob.
void EmitRecordWithPath(unsigned Abbrev, RecordDataRef Record,
StringRef Path);
- /// \brief Add a version tuple to the given record
+ /// Add a version tuple to the given record
void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record);
- /// \brief Retrieve or create a submodule ID for this module, or return 0 if
+ /// Retrieve or create a submodule ID for this module, or return 0 if
/// the submodule is neither local (a submodle of the currently-written module)
/// nor from an imported module.
unsigned getLocalOrImportedSubmoduleID(Module *Mod);
- /// \brief Note that the identifier II occurs at the given offset
+ /// Note that the identifier II occurs at the given offset
/// within the identifier table.
void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset);
- /// \brief Note that the selector Sel occurs at the given offset
+ /// Note that the selector Sel occurs at the given offset
/// within the method pool/selector table.
void SetSelectorOffset(Selector Sel, uint32_t Offset);
- /// \brief Record an ID for the given switch-case statement.
+ /// Record an ID for the given switch-case statement.
unsigned RecordSwitchCaseID(SwitchCase *S);
- /// \brief Retrieve the ID for the given switch-case statement.
+ /// Retrieve the ID for the given switch-case statement.
unsigned getSwitchCaseID(SwitchCase *S);
void ClearSwitchCaseIDs();
@@ -743,21 +742,21 @@ private:
const RecordDecl *Record) override;
};
-/// \brief An object for streaming information to a record.
+/// An object for streaming information to a record.
class ASTRecordWriter {
ASTWriter *Writer;
ASTWriter::RecordDataImpl *Record;
- /// \brief Statements that we've encountered while serializing a
+ /// Statements that we've encountered while serializing a
/// declaration or type.
SmallVector<Stmt *, 16> StmtsToEmit;
- /// \brief Indices of record elements that describe offsets within the
+ /// Indices of record elements that describe offsets within the
/// bitcode. These will be converted to offsets relative to the current
/// record when emitted.
SmallVector<unsigned, 8> OffsetIndices;
- /// \brief Flush all of the statements and expressions that have
+ /// Flush all of the statements and expressions that have
/// been added to the queue via AddStmt().
void FlushStmts();
void FlushSubStmts();
@@ -787,10 +786,10 @@ public:
ASTRecordWriter(const ASTRecordWriter &) = delete;
ASTRecordWriter &operator=(const ASTRecordWriter &) = delete;
- /// \brief Extract the underlying record storage.
+ /// Extract the underlying record storage.
ASTWriter::RecordDataImpl &getRecordData() const { return *Record; }
- /// \brief Minimal vector-like interface.
+ /// Minimal vector-like interface.
/// @{
void push_back(uint64_t N) { Record->push_back(N); }
template<typename InputIterator>
@@ -802,7 +801,7 @@ public:
uint64_t &operator[](size_t N) { return (*Record)[N]; }
/// @}
- /// \brief Emit the record to the stream, followed by its substatements, and
+ /// Emit the record to the stream, followed by its substatements, and
/// return its offset.
// FIXME: Allow record producers to suggest Abbrevs.
uint64_t Emit(unsigned Code, unsigned Abbrev = 0) {
@@ -813,7 +812,7 @@ public:
return Offset;
}
- /// \brief Emit the record to the stream, preceded by its substatements.
+ /// Emit the record to the stream, preceded by its substatements.
uint64_t EmitStmt(unsigned Code, unsigned Abbrev = 0) {
FlushSubStmts();
PrepareToEmit(Writer->Stream.GetCurrentBitNo());
@@ -821,14 +820,14 @@ public:
return Writer->Stream.GetCurrentBitNo();
}
- /// \brief Add a bit offset into the record. This will be converted into an
+ /// Add a bit offset into the record. This will be converted into an
/// offset relative to the current record when emitted.
void AddOffset(uint64_t BitOffset) {
OffsetIndices.push_back(Record->size());
Record->push_back(BitOffset);
}
- /// \brief Add the given statement or expression to the queue of
+ /// Add the given statement or expression to the queue of
/// statements to emit.
///
/// This routine should be used when emitting types and declarations
@@ -839,74 +838,74 @@ public:
StmtsToEmit.push_back(S);
}
- /// \brief Add a definition for the given function to the queue of statements
+ /// Add a definition for the given function to the queue of statements
/// to emit.
void AddFunctionDefinition(const FunctionDecl *FD);
- /// \brief Emit a source location.
+ /// Emit a source location.
void AddSourceLocation(SourceLocation Loc) {
return Writer->AddSourceLocation(Loc, *Record);
}
- /// \brief Emit a source range.
+ /// Emit a source range.
void AddSourceRange(SourceRange Range) {
return Writer->AddSourceRange(Range, *Record);
}
- /// \brief Emit an integral value.
+ /// Emit an integral value.
void AddAPInt(const llvm::APInt &Value);
- /// \brief Emit a signed integral value.
+ /// Emit a signed integral value.
void AddAPSInt(const llvm::APSInt &Value);
- /// \brief Emit a floating-point value.
+ /// Emit a floating-point value.
void AddAPFloat(const llvm::APFloat &Value);
- /// \brief Emit a reference to an identifier.
+ /// Emit a reference to an identifier.
void AddIdentifierRef(const IdentifierInfo *II) {
return Writer->AddIdentifierRef(II, *Record);
}
- /// \brief Emit a Selector (which is a smart pointer reference).
+ /// Emit a Selector (which is a smart pointer reference).
void AddSelectorRef(Selector S);
- /// \brief Emit a CXXTemporary.
+ /// Emit a CXXTemporary.
void AddCXXTemporary(const CXXTemporary *Temp);
- /// \brief Emit a C++ base specifier.
+ /// Emit a C++ base specifier.
void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base);
- /// \brief Emit a set of C++ base specifiers.
+ /// Emit a set of C++ base specifiers.
void AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases);
- /// \brief Emit a reference to a type.
+ /// Emit a reference to a type.
void AddTypeRef(QualType T) {
return Writer->AddTypeRef(T, *Record);
}
- /// \brief Emits a reference to a declarator info.
+ /// Emits a reference to a declarator info.
void AddTypeSourceInfo(TypeSourceInfo *TInfo);
- /// \brief Emits a type with source-location information.
+ /// Emits source location information for a type. Does not emit the type.
void AddTypeLoc(TypeLoc TL);
- /// \brief Emits a template argument location info.
+ /// Emits a template argument location info.
void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
const TemplateArgumentLocInfo &Arg);
- /// \brief Emits a template argument location.
+ /// Emits a template argument location.
void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg);
- /// \brief Emits an AST template argument list info.
+ /// Emits an AST template argument list info.
void AddASTTemplateArgumentListInfo(
const ASTTemplateArgumentListInfo *ASTTemplArgList);
- /// \brief Emit a reference to a declaration.
+ /// Emit a reference to a declaration.
void AddDeclRef(const Decl *D) {
return Writer->AddDeclRef(D, *Record);
}
- /// \brief Emit a declaration name.
+ /// Emit a declaration name.
void AddDeclarationName(DeclarationName Name);
void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
@@ -915,52 +914,52 @@ public:
void AddQualifierInfo(const QualifierInfo &Info);
- /// \brief Emit a nested name specifier.
+ /// Emit a nested name specifier.
void AddNestedNameSpecifier(NestedNameSpecifier *NNS);
- /// \brief Emit a nested name specifier with source-location information.
+ /// Emit a nested name specifier with source-location information.
void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
- /// \brief Emit a template name.
+ /// Emit a template name.
void AddTemplateName(TemplateName Name);
- /// \brief Emit a template argument.
+ /// Emit a template argument.
void AddTemplateArgument(const TemplateArgument &Arg);
- /// \brief Emit a template parameter list.
+ /// Emit a template parameter list.
void AddTemplateParameterList(const TemplateParameterList *TemplateParams);
- /// \brief Emit a template argument list.
+ /// Emit a template argument list.
void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs);
- /// \brief Emit a UnresolvedSet structure.
+ /// Emit a UnresolvedSet structure.
void AddUnresolvedSet(const ASTUnresolvedSet &Set);
- /// \brief Emit a CXXCtorInitializer array.
+ /// Emit a CXXCtorInitializer array.
void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer *> CtorInits);
void AddCXXDefinitionData(const CXXRecordDecl *D);
- /// \brief Emit a string.
+ /// Emit a string.
void AddString(StringRef Str) {
return Writer->AddString(Str, *Record);
}
- /// \brief Emit a path.
+ /// Emit a path.
void AddPath(StringRef Path) {
return Writer->AddPath(Path, *Record);
}
- /// \brief Emit a version tuple.
+ /// Emit a version tuple.
void AddVersionTuple(const VersionTuple &Version) {
return Writer->AddVersionTuple(Version, *Record);
}
- /// \brief Emit a list of attributes.
+ /// Emit a list of attributes.
void AddAttributes(ArrayRef<const Attr*> Attrs);
};
-/// \brief AST and semantic-analysis consumer that generates a
+/// AST and semantic-analysis consumer that generates a
/// precompiled header from the parsed source code.
class PCHGenerator : public SemaConsumer {
const Preprocessor &PP;
diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h
index 24bfadd0f8677..2f909965db7ef 100644
--- a/include/clang/Serialization/ContinuousRangeMap.h
+++ b/include/clang/Serialization/ContinuousRangeMap.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include <algorithm>
#include <cassert>
@@ -23,7 +24,7 @@
namespace clang {
-/// \brief A map from continuous integer ranges to some value, with a very
+/// A map from continuous integer ranges to some value, with a very
/// specialized interface.
///
/// CRM maps from integer ranges to values. The ranges are continuous, i.e.
@@ -106,7 +107,7 @@ public:
reference back() { return Rep.back(); }
const_reference back() const { return Rep.back(); }
- /// \brief An object that helps properly build a continuous range map
+ /// An object that helps properly build a continuous range map
/// from a set of values.
class Builder {
ContinuousRangeMap &Self;
@@ -117,7 +118,7 @@ public:
Builder &operator=(const Builder&) = delete;
~Builder() {
- std::sort(Self.Rep.begin(), Self.Rep.end(), Compare());
+ llvm::sort(Self.Rep.begin(), Self.Rep.end(), Compare());
std::unique(Self.Rep.begin(), Self.Rep.end(),
[](const_reference A, const_reference B) {
// FIXME: we should not allow any duplicate keys, but there are a lot of
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
index 0f14eca0fd86a..f48d0cf17c493 100644
--- a/include/clang/Serialization/GlobalModuleIndex.h
+++ b/include/clang/Serialization/GlobalModuleIndex.h
@@ -47,7 +47,7 @@ using llvm::SmallVectorImpl;
using llvm::StringRef;
using serialization::ModuleFile;
-/// \brief A global index for a set of module files, providing information about
+/// A global index for a set of module files, providing information about
/// the identifiers within those module files.
///
/// The global index is an aid for name lookup into modules, offering a central
@@ -59,64 +59,64 @@ using serialization::ModuleFile;
/// imported, and can be queried to determine which modules the current
/// translation could or should load to fix a problem.
class GlobalModuleIndex {
- /// \brief Buffer containing the index file, which is lazily accessed so long
+ /// Buffer containing the index file, which is lazily accessed so long
/// as the global module index is live.
std::unique_ptr<llvm::MemoryBuffer> Buffer;
- /// \brief The hash table.
+ /// The hash table.
///
/// This pointer actually points to a IdentifierIndexTable object,
/// but that type is only accessible within the implementation of
/// GlobalModuleIndex.
void *IdentifierIndex;
- /// \brief Information about a given module file.
+ /// Information about a given module file.
struct ModuleInfo {
ModuleInfo() : File(), Size(), ModTime() { }
- /// \brief The module file, once it has been resolved.
+ /// The module file, once it has been resolved.
ModuleFile *File;
- /// \brief The module file name.
+ /// The module file name.
std::string FileName;
- /// \brief Size of the module file at the time the global index was built.
+ /// Size of the module file at the time the global index was built.
off_t Size;
- /// \brief Modification time of the module file at the time the global
+ /// Modification time of the module file at the time the global
/// index was built.
time_t ModTime;
- /// \brief The module IDs on which this module directly depends.
+ /// The module IDs on which this module directly depends.
/// FIXME: We don't really need a vector here.
llvm::SmallVector<unsigned, 4> Dependencies;
};
- /// \brief A mapping from module IDs to information about each module.
+ /// A mapping from module IDs to information about each module.
///
/// This vector may have gaps, if module files have been removed or have
/// been updated since the index was built. A gap is indicated by an empty
/// file name.
llvm::SmallVector<ModuleInfo, 16> Modules;
- /// \brief Lazily-populated mapping from module files to their
+ /// Lazily-populated mapping from module files to their
/// corresponding index into the \c Modules vector.
llvm::DenseMap<ModuleFile *, unsigned> ModulesByFile;
- /// \brief The set of modules that have not yet been resolved.
+ /// The set of modules that have not yet been resolved.
///
/// The string is just the name of the module itself, which maps to the
/// module ID.
llvm::StringMap<unsigned> UnresolvedModules;
- /// \brief The number of identifier lookups we performed.
+ /// The number of identifier lookups we performed.
unsigned NumIdentifierLookups;
- /// \brief The number of identifier lookup hits, where we recognize the
+ /// The number of identifier lookup hits, where we recognize the
/// identifier.
unsigned NumIdentifierLookupHits;
- /// \brief Internal constructor. Use \c readIndex() to read an index.
+ /// Internal constructor. Use \c readIndex() to read an index.
explicit GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer,
llvm::BitstreamCursor Cursor);
@@ -126,20 +126,20 @@ class GlobalModuleIndex {
public:
~GlobalModuleIndex();
- /// \brief An error code returned when trying to read an index.
+ /// An error code returned when trying to read an index.
enum ErrorCode {
- /// \brief No error occurred.
+ /// No error occurred.
EC_None,
- /// \brief No index was found.
+ /// No index was found.
EC_NotFound,
- /// \brief Some other process is currently building the index; it is not
+ /// Some other process is currently building the index; it is not
/// available yet.
EC_Building,
- /// \brief There was an unspecified I/O error reading or writing the index.
+ /// There was an unspecified I/O error reading or writing the index.
EC_IOError
};
- /// \brief Read a global index file for the given directory.
+ /// Read a global index file for the given directory.
///
/// \param Path The path to the specific module cache where the module files
/// for the intended configuration reside.
@@ -149,26 +149,26 @@ public:
static std::pair<GlobalModuleIndex *, ErrorCode>
readIndex(StringRef Path);
- /// \brief Returns an iterator for identifiers stored in the index table.
+ /// Returns an iterator for identifiers stored in the index table.
///
/// The caller accepts ownership of the returned object.
IdentifierIterator *createIdentifierIterator() const;
- /// \brief Retrieve the set of modules that have up-to-date indexes.
+ /// Retrieve the set of modules that have up-to-date indexes.
///
/// \param ModuleFiles Will be populated with the set of module files that
/// have been indexed.
void getKnownModules(SmallVectorImpl<ModuleFile *> &ModuleFiles);
- /// \brief Retrieve the set of module files on which the given module file
+ /// Retrieve the set of module files on which the given module file
/// directly depends.
void getModuleDependencies(ModuleFile *File,
SmallVectorImpl<ModuleFile *> &Dependencies);
- /// \brief A set of module files in which we found a result.
+ /// A set of module files in which we found a result.
typedef llvm::SmallPtrSet<ModuleFile *, 4> HitSet;
- /// \brief Look for all of the module files with information about the given
+ /// Look for all of the module files with information about the given
/// identifier, e.g., a global function, variable, or type with that name.
///
/// \param Name The identifier to look for.
@@ -179,19 +179,19 @@ public:
/// \returns true if the identifier is known to the index, false otherwise.
bool lookupIdentifier(StringRef Name, HitSet &Hits);
- /// \brief Note that the given module file has been loaded.
+ /// Note that the given module file has been loaded.
///
/// \returns false if the global module index has information about this
/// module file, and true otherwise.
bool loadedModuleFile(ModuleFile *File);
- /// \brief Print statistics to standard error.
+ /// Print statistics to standard error.
void printStats();
- /// \brief Print debugging view to standard error.
+ /// Print debugging view to standard error.
void dump();
- /// \brief Write a global index into the given
+ /// Write a global index into the given
///
/// \param FileMgr The file manager to use to load module files.
/// \param PCHContainerRdr - The PCHContainerOperations to use for loading and
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 4e4bf44f34920..653981b1427ca 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -1,4 +1,4 @@
-//===--- Module.h - Module description --------------------------*- C++ -*-===//
+//===- Module.h - Module description ----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,45 +15,52 @@
#ifndef LLVM_CLANG_SERIALIZATION_MODULE_H
#define LLVM_CLANG_SERIALIZATION_MODULE_H
-#include "clang/Basic/FileManager.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ContinuousRangeMap.h"
#include "clang/Serialization/ModuleFileExtension.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Support/Endian.h"
+#include <cassert>
+#include <cstdint>
#include <memory>
#include <string>
-
-namespace llvm {
-template <typename Info> class OnDiskChainedHashTable;
-template <typename Info> class OnDiskIterableChainedHashTable;
-}
+#include <vector>
namespace clang {
-class DeclContext;
-class Module;
+class FileEntry;
namespace serialization {
-namespace reader {
- class ASTDeclContextNameLookupTrait;
-}
-
-/// \brief Specifies the kind of module that has been loaded.
+/// Specifies the kind of module that has been loaded.
enum ModuleKind {
- MK_ImplicitModule, ///< File is an implicitly-loaded module.
- MK_ExplicitModule, ///< File is an explicitly-loaded module.
- MK_PCH, ///< File is a PCH file treated as such.
- MK_Preamble, ///< File is a PCH file treated as the preamble.
- MK_MainFile, ///< File is a PCH file treated as the actual main file.
- MK_PrebuiltModule ///< File is from a prebuilt module path.
+ /// File is an implicitly-loaded module.
+ MK_ImplicitModule,
+
+ /// File is an explicitly-loaded module.
+ MK_ExplicitModule,
+
+ /// File is a PCH file treated as such.
+ MK_PCH,
+
+ /// File is a PCH file treated as the preamble.
+ MK_Preamble,
+
+ /// File is a PCH file treated as the actual main file.
+ MK_MainFile,
+
+ /// File is from a prebuilt module path.
+ MK_PrebuiltModule
};
-/// \brief The input file that has been loaded from this AST file, along with
+/// The input file that has been loaded from this AST file, along with
/// bools indicating whether this was an overridden buffer or if it was
/// out-of-date or not-found.
class InputFile {
@@ -65,7 +72,8 @@ class InputFile {
llvm::PointerIntPair<const FileEntry *, 2, unsigned> Val;
public:
- InputFile() {}
+ InputFile() = default;
+
InputFile(const FileEntry *File,
bool isOverridden = false, bool isOutOfDate = false) {
assert(!(isOverridden && isOutOfDate) &&
@@ -90,7 +98,7 @@ public:
bool isNotFound() const { return Val.getInt() == NotFound; }
};
-/// \brief Information about a module that has been loaded by the ASTReader.
+/// Information about a module that has been loaded by the ASTReader.
///
/// Each instance of the Module class corresponds to a single AST file, which
/// may be a precompiled header, precompiled preamble, a module, or an AST file
@@ -105,81 +113,84 @@ public:
// === General information ===
- /// \brief The index of this module in the list of modules.
+ /// The index of this module in the list of modules.
unsigned Index = 0;
- /// \brief The type of this module.
+ /// The type of this module.
ModuleKind Kind;
- /// \brief The file name of the module file.
+ /// The file name of the module file.
std::string FileName;
- /// \brief The name of the module.
+ /// The name of the module.
std::string ModuleName;
- /// \brief The base directory of the module.
+ /// The base directory of the module.
std::string BaseDirectory;
std::string getTimestampFilename() const {
return FileName + ".timestamp";
}
- /// \brief The original source file name that was used to build the
+ /// The original source file name that was used to build the
/// primary AST file, which may have been modified for
/// relocatable-pch support.
std::string OriginalSourceFileName;
- /// \brief The actual original source file name that was used to
+ /// The actual original source file name that was used to
/// build this AST file.
std::string ActualOriginalSourceFileName;
- /// \brief The file ID for the original source file that was used to
+ /// The file ID for the original source file that was used to
/// build this AST file.
FileID OriginalSourceFileID;
- /// \brief The directory that the PCH was originally created in. Used to
+ /// The directory that the PCH was originally created in. Used to
/// allow resolving headers even after headers+PCH was moved to a new path.
std::string OriginalDir;
std::string ModuleMapPath;
- /// \brief Whether this precompiled header is a relocatable PCH file.
+ /// Whether this precompiled header is a relocatable PCH file.
bool RelocatablePCH = false;
- /// \brief Whether timestamps are included in this module file.
+ /// Whether timestamps are included in this module file.
bool HasTimestamps = false;
- /// \brief The file entry for the module file.
+ /// Whether the PCH has a corresponding object file.
+ bool PCHHasObjectFile = false;
+
+ /// The file entry for the module file.
const FileEntry *File = nullptr;
/// The signature of the module file, which may be used instead of the size
/// and modification time to identify this particular file.
ASTFileSignature Signature;
- /// \brief Whether this module has been directly imported by the
+ /// Whether this module has been directly imported by the
/// user.
bool DirectlyImported = false;
- /// \brief The generation of which this module file is a part.
+ /// The generation of which this module file is a part.
unsigned Generation;
/// The memory buffer that stores the data associated with
/// this AST file, owned by the PCMCache in the ModuleManager.
llvm::MemoryBuffer *Buffer;
- /// \brief The size of this file, in bits.
+ /// The size of this file, in bits.
uint64_t SizeInBits = 0;
- /// \brief The global bit offset (or base) of this module
+ /// The global bit offset (or base) of this module
uint64_t GlobalBitOffset = 0;
- /// \brief The serialized bitstream data for this file.
+ /// The serialized bitstream data for this file.
StringRef Data;
- /// \brief The main bitstream cursor for the main block.
+ /// The main bitstream cursor for the main block.
llvm::BitstreamCursor Stream;
- /// \brief The source location where the module was explicitly or implicitly
+ /// The source location where the module was explicitly or implicitly
/// imported in the local translation unit.
///
/// If module A depends on and imports module B, both modules will have the
@@ -190,10 +201,10 @@ public:
/// made visible, just when the first submodule of that module was imported.
SourceLocation DirectImportLoc;
- /// \brief The source location where this module was first imported.
+ /// The source location where this module was first imported.
SourceLocation ImportLoc;
- /// \brief The first source location in this module.
+ /// The first source location in this module.
SourceLocation FirstLoc;
/// The list of extension readers that are attached to this module
@@ -205,20 +216,21 @@ public:
StringRef ModuleOffsetMap;
// === Input Files ===
- /// \brief The cursor to the start of the input-files block.
+
+ /// The cursor to the start of the input-files block.
llvm::BitstreamCursor InputFilesCursor;
- /// \brief Offsets for all of the input file entries in the AST file.
+ /// Offsets for all of the input file entries in the AST file.
const llvm::support::unaligned_uint64_t *InputFileOffsets = nullptr;
- /// \brief The input files that have been loaded from this AST file.
+ /// The input files that have been loaded from this AST file.
std::vector<InputFile> InputFilesLoaded;
// All user input files reside at the index range [0, NumUserInputFiles), and
// system input files reside at [NumUserInputFiles, InputFilesLoaded.size()).
unsigned NumUserInputFiles = 0;
- /// \brief If non-zero, specifies the time when we last validated input
+ /// If non-zero, specifies the time when we last validated input
/// files. Zero means we never validated them.
///
/// The time is specified in seconds since the start of the Epoch.
@@ -226,153 +238,160 @@ public:
// === Source Locations ===
- /// \brief Cursor used to read source location entries.
+ /// Cursor used to read source location entries.
llvm::BitstreamCursor SLocEntryCursor;
- /// \brief The number of source location entries in this AST file.
+ /// The number of source location entries in this AST file.
unsigned LocalNumSLocEntries = 0;
- /// \brief The base ID in the source manager's view of this module.
+ /// The base ID in the source manager's view of this module.
int SLocEntryBaseID = 0;
- /// \brief The base offset in the source manager's view of this module.
+ /// The base offset in the source manager's view of this module.
unsigned SLocEntryBaseOffset = 0;
- /// \brief Offsets for all of the source location entries in the
+ /// Offsets for all of the source location entries in the
/// AST file.
const uint32_t *SLocEntryOffsets = nullptr;
- /// \brief SLocEntries that we're going to preload.
+ /// SLocEntries that we're going to preload.
SmallVector<uint64_t, 4> PreloadSLocEntries;
- /// \brief Remapping table for source locations in this module.
+ /// Remapping table for source locations in this module.
ContinuousRangeMap<uint32_t, int, 2> SLocRemap;
// === Identifiers ===
- /// \brief The number of identifiers in this AST file.
+ /// The number of identifiers in this AST file.
unsigned LocalNumIdentifiers = 0;
- /// \brief Offsets into the identifier table data.
+ /// Offsets into the identifier table data.
///
/// This array is indexed by the identifier ID (-1), and provides
/// the offset into IdentifierTableData where the string data is
/// stored.
const uint32_t *IdentifierOffsets = nullptr;
- /// \brief Base identifier ID for identifiers local to this module.
+ /// Base identifier ID for identifiers local to this module.
serialization::IdentID BaseIdentifierID = 0;
- /// \brief Remapping table for identifier IDs in this module.
+ /// Remapping table for identifier IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap;
- /// \brief Actual data for the on-disk hash table of identifiers.
+ /// Actual data for the on-disk hash table of identifiers.
///
/// This pointer points into a memory buffer, where the on-disk hash
/// table for identifiers actually lives.
const char *IdentifierTableData = nullptr;
- /// \brief A pointer to an on-disk hash table of opaque type
+ /// A pointer to an on-disk hash table of opaque type
/// IdentifierHashTable.
void *IdentifierLookupTable = nullptr;
- /// \brief Offsets of identifiers that we're going to preload within
+ /// Offsets of identifiers that we're going to preload within
/// IdentifierTableData.
std::vector<unsigned> PreloadIdentifierOffsets;
// === Macros ===
- /// \brief The cursor to the start of the preprocessor block, which stores
+ /// The cursor to the start of the preprocessor block, which stores
/// all of the macro definitions.
llvm::BitstreamCursor MacroCursor;
- /// \brief The number of macros in this AST file.
+ /// The number of macros in this AST file.
unsigned LocalNumMacros = 0;
- /// \brief Offsets of macros in the preprocessor block.
+ /// Offsets of macros in the preprocessor block.
///
/// This array is indexed by the macro ID (-1), and provides
/// the offset into the preprocessor block where macro definitions are
/// stored.
const uint32_t *MacroOffsets = nullptr;
- /// \brief Base macro ID for macros local to this module.
+ /// Base macro ID for macros local to this module.
serialization::MacroID BaseMacroID = 0;
- /// \brief Remapping table for macro IDs in this module.
+ /// Remapping table for macro IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> MacroRemap;
- /// \brief The offset of the start of the set of defined macros.
+ /// The offset of the start of the set of defined macros.
uint64_t MacroStartOffset = 0;
// === Detailed PreprocessingRecord ===
- /// \brief The cursor to the start of the (optional) detailed preprocessing
+ /// The cursor to the start of the (optional) detailed preprocessing
/// record block.
llvm::BitstreamCursor PreprocessorDetailCursor;
- /// \brief The offset of the start of the preprocessor detail cursor.
+ /// The offset of the start of the preprocessor detail cursor.
uint64_t PreprocessorDetailStartOffset = 0;
- /// \brief Base preprocessed entity ID for preprocessed entities local to
+ /// Base preprocessed entity ID for preprocessed entities local to
/// this module.
serialization::PreprocessedEntityID BasePreprocessedEntityID = 0;
- /// \brief Remapping table for preprocessed entity IDs in this module.
+ /// Remapping table for preprocessed entity IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap;
const PPEntityOffset *PreprocessedEntityOffsets = nullptr;
unsigned NumPreprocessedEntities = 0;
+ /// Base ID for preprocessed skipped ranges local to this module.
+ unsigned BasePreprocessedSkippedRangeID = 0;
+
+ const PPSkippedRange *PreprocessedSkippedRangeOffsets = nullptr;
+ unsigned NumPreprocessedSkippedRanges = 0;
+
// === Header search information ===
- /// \brief The number of local HeaderFileInfo structures.
+ /// The number of local HeaderFileInfo structures.
unsigned LocalNumHeaderFileInfos = 0;
- /// \brief Actual data for the on-disk hash table of header file
+ /// Actual data for the on-disk hash table of header file
/// information.
///
/// This pointer points into a memory buffer, where the on-disk hash
/// table for header file information actually lives.
const char *HeaderFileInfoTableData = nullptr;
- /// \brief The on-disk hash table that contains information about each of
+ /// The on-disk hash table that contains information about each of
/// the header files.
void *HeaderFileInfoTable = nullptr;
// === Submodule information ===
- /// \brief The number of submodules in this module.
+
+ /// The number of submodules in this module.
unsigned LocalNumSubmodules = 0;
- /// \brief Base submodule ID for submodules local to this module.
+ /// Base submodule ID for submodules local to this module.
serialization::SubmoduleID BaseSubmoduleID = 0;
- /// \brief Remapping table for submodule IDs in this module.
+ /// Remapping table for submodule IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> SubmoduleRemap;
// === Selectors ===
- /// \brief The number of selectors new to this file.
+ /// The number of selectors new to this file.
///
/// This is the number of entries in SelectorOffsets.
unsigned LocalNumSelectors = 0;
- /// \brief Offsets into the selector lookup table's data array
+ /// Offsets into the selector lookup table's data array
/// where each selector resides.
const uint32_t *SelectorOffsets = nullptr;
- /// \brief Base selector ID for selectors local to this module.
+ /// Base selector ID for selectors local to this module.
serialization::SelectorID BaseSelectorID = 0;
- /// \brief Remapping table for selector IDs in this module.
+ /// Remapping table for selector IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> SelectorRemap;
- /// \brief A pointer to the character data that comprises the selector table
+ /// A pointer to the character data that comprises the selector table
///
/// The SelectorOffsets table refers into this memory.
const unsigned char *SelectorLookupTableData = nullptr;
- /// \brief A pointer to an on-disk hash table of opaque type
+ /// A pointer to an on-disk hash table of opaque type
/// ASTSelectorLookupTable.
///
/// This hash table provides the IDs of all selectors, and the associated
@@ -386,20 +405,20 @@ public:
/// jump around with these in context.
llvm::BitstreamCursor DeclsCursor;
- /// \brief The number of declarations in this AST file.
+ /// The number of declarations in this AST file.
unsigned LocalNumDecls = 0;
- /// \brief Offset of each declaration within the bitstream, indexed
+ /// Offset of each declaration within the bitstream, indexed
/// by the declaration ID (-1).
const DeclOffset *DeclOffsets = nullptr;
- /// \brief Base declaration ID for declarations local to this module.
+ /// Base declaration ID for declarations local to this module.
serialization::DeclID BaseDeclID = 0;
- /// \brief Remapping table for declaration IDs in this module.
+ /// Remapping table for declaration IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> DeclRemap;
- /// \brief Mapping from the module files that this module file depends on
+ /// Mapping from the module files that this module file depends on
/// to the base declaration ID for that module as it is understood within this
/// module.
///
@@ -408,64 +427,64 @@ public:
/// as a local ID (for this module file).
llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs;
- /// \brief Array of file-level DeclIDs sorted by file.
+ /// Array of file-level DeclIDs sorted by file.
const serialization::DeclID *FileSortedDecls = nullptr;
unsigned NumFileSortedDecls = 0;
- /// \brief Array of category list location information within this
+ /// Array of category list location information within this
/// module file, sorted by the definition ID.
const serialization::ObjCCategoriesInfo *ObjCCategoriesMap = nullptr;
- /// \brief The number of redeclaration info entries in ObjCCategoriesMap.
+ /// The number of redeclaration info entries in ObjCCategoriesMap.
unsigned LocalNumObjCCategoriesInMap = 0;
- /// \brief The Objective-C category lists for categories known to this
+ /// The Objective-C category lists for categories known to this
/// module.
SmallVector<uint64_t, 1> ObjCCategories;
// === Types ===
- /// \brief The number of types in this AST file.
+ /// The number of types in this AST file.
unsigned LocalNumTypes = 0;
- /// \brief Offset of each type within the bitstream, indexed by the
+ /// Offset of each type within the bitstream, indexed by the
/// type ID, or the representation of a Type*.
const uint32_t *TypeOffsets = nullptr;
- /// \brief Base type ID for types local to this module as represented in
+ /// Base type ID for types local to this module as represented in
/// the global type ID space.
serialization::TypeID BaseTypeIndex = 0;
- /// \brief Remapping table for type IDs in this module.
+ /// Remapping table for type IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> TypeRemap;
// === Miscellaneous ===
- /// \brief Diagnostic IDs and their mappings that the user changed.
+ /// Diagnostic IDs and their mappings that the user changed.
SmallVector<uint64_t, 8> PragmaDiagMappings;
- /// \brief List of modules which depend on this module
+ /// List of modules which depend on this module
llvm::SetVector<ModuleFile *> ImportedBy;
- /// \brief List of modules which this module depends on
+ /// List of modules which this module depends on
llvm::SetVector<ModuleFile *> Imports;
- /// \brief Determine whether this module was directly imported at
+ /// Determine whether this module was directly imported at
/// any point during translation.
bool isDirectlyImported() const { return DirectlyImported; }
- /// \brief Is this a module file for a module (rather than a PCH or similar).
+ /// Is this a module file for a module (rather than a PCH or similar).
bool isModule() const {
return Kind == MK_ImplicitModule || Kind == MK_ExplicitModule ||
Kind == MK_PrebuiltModule;
}
- /// \brief Dump debugging output for this module.
+ /// Dump debugging output for this module.
void dump();
};
-} // end namespace serialization
+} // namespace serialization
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_SERIALIZATION_MODULE_H
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index 147a6910aa295..e101e60b21a3d 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -45,45 +45,45 @@ class PCHContainerReader;
namespace serialization {
-/// \brief Manages the set of modules loaded by an AST reader.
+/// Manages the set of modules loaded by an AST reader.
class ModuleManager {
- /// \brief The chain of AST files, in the order in which we started to load
+ /// The chain of AST files, in the order in which we started to load
/// them (this order isn't really useful for anything).
SmallVector<std::unique_ptr<ModuleFile>, 2> Chain;
- /// \brief The chain of non-module PCH files. The first entry is the one named
+ /// The chain of non-module PCH files. The first entry is the one named
/// by the user, the last one is the one that doesn't depend on anything
/// further.
SmallVector<ModuleFile *, 2> PCHChain;
- // \brief The roots of the dependency DAG of AST files. This is used
+ // The roots of the dependency DAG of AST files. This is used
// to implement short-circuiting logic when running DFS over the dependencies.
SmallVector<ModuleFile *, 2> Roots;
- /// \brief All loaded modules, indexed by name.
+ /// All loaded modules, indexed by name.
llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;
- /// \brief FileManager that handles translating between filenames and
+ /// FileManager that handles translating between filenames and
/// FileEntry *.
FileManager &FileMgr;
/// Cache of PCM files.
IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
- /// \brief Knows how to unwrap module containers.
+ /// Knows how to unwrap module containers.
const PCHContainerReader &PCHContainerRdr;
- /// \brief Preprocessor's HeaderSearchInfo containing the module map.
+ /// Preprocessor's HeaderSearchInfo containing the module map.
const HeaderSearch &HeaderSearchInfo;
- /// \brief A lookup of in-memory (virtual file) buffers
+ /// A lookup of in-memory (virtual file) buffers
llvm::DenseMap<const FileEntry *, std::unique_ptr<llvm::MemoryBuffer>>
InMemoryBuffers;
- /// \brief The visitation order.
+ /// The visitation order.
SmallVector<ModuleFile *, 4> VisitOrder;
- /// \brief The list of module files that both we and the global module index
+ /// The list of module files that both we and the global module index
/// know about.
///
/// Either the global index or the module manager may have modules that the
@@ -93,13 +93,13 @@ class ModuleManager {
/// known to the global index.
SmallVector<ModuleFile *, 4> ModulesInCommonWithGlobalIndex;
- /// \brief The global module index, if one is attached.
+ /// The global module index, if one is attached.
///
/// The global module index will actually be owned by the ASTReader; this is
/// just an non-owning pointer.
GlobalModuleIndex *GlobalIndex = nullptr;
- /// \brief State used by the "visit" operation to avoid malloc traffic in
+ /// State used by the "visit" operation to avoid malloc traffic in
/// calls to visit().
struct VisitState {
explicit VisitState(unsigned N) : VisitNumber(N, 0) {
@@ -110,22 +110,22 @@ class ModuleManager {
delete NextState;
}
- /// \brief The stack used when marking the imports of a particular module
+ /// The stack used when marking the imports of a particular module
/// as not-to-be-visited.
SmallVector<ModuleFile *, 4> Stack;
- /// \brief The visit number of each module file, which indicates when
+ /// The visit number of each module file, which indicates when
/// this module file was last visited.
SmallVector<unsigned, 4> VisitNumber;
- /// \brief The next visit number to use to mark visited module files.
+ /// The next visit number to use to mark visited module files.
unsigned NextVisitNumber = 1;
- /// \brief The next visit state.
+ /// The next visit state.
VisitState *NextState = nullptr;
};
- /// \brief The first visit() state in the chain.
+ /// The first visit() state in the chain.
VisitState *FirstVisitState = nullptr;
VisitState *allocateVisitState();
@@ -145,74 +145,74 @@ public:
const HeaderSearch &HeaderSearchInfo);
~ModuleManager();
- /// \brief Forward iterator to traverse all loaded modules.
+ /// Forward iterator to traverse all loaded modules.
ModuleIterator begin() { return Chain.begin(); }
- /// \brief Forward iterator end-point to traverse all loaded modules
+ /// Forward iterator end-point to traverse all loaded modules
ModuleIterator end() { return Chain.end(); }
- /// \brief Const forward iterator to traverse all loaded modules.
+ /// Const forward iterator to traverse all loaded modules.
ModuleConstIterator begin() const { return Chain.begin(); }
- /// \brief Const forward iterator end-point to traverse all loaded modules
+ /// Const forward iterator end-point to traverse all loaded modules
ModuleConstIterator end() const { return Chain.end(); }
- /// \brief Reverse iterator to traverse all loaded modules.
+ /// Reverse iterator to traverse all loaded modules.
ModuleReverseIterator rbegin() { return Chain.rbegin(); }
- /// \brief Reverse iterator end-point to traverse all loaded modules.
+ /// Reverse iterator end-point to traverse all loaded modules.
ModuleReverseIterator rend() { return Chain.rend(); }
- /// \brief A range covering the PCH and preamble module files loaded.
+ /// A range covering the PCH and preamble module files loaded.
llvm::iterator_range<SmallVectorImpl<ModuleFile *>::const_iterator>
pch_modules() const {
return llvm::make_range(PCHChain.begin(), PCHChain.end());
}
- /// \brief Returns the primary module associated with the manager, that is,
+ /// Returns the primary module associated with the manager, that is,
/// the first module loaded
ModuleFile &getPrimaryModule() { return *Chain[0]; }
- /// \brief Returns the primary module associated with the manager, that is,
+ /// Returns the primary module associated with the manager, that is,
/// the first module loaded.
ModuleFile &getPrimaryModule() const { return *Chain[0]; }
- /// \brief Returns the module associated with the given index
+ /// Returns the module associated with the given index
ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; }
- /// \brief Returns the module associated with the given file name.
+ /// Returns the module associated with the given file name.
ModuleFile *lookupByFileName(StringRef FileName) const;
- /// \brief Returns the module associated with the given module name.
+ /// Returns the module associated with the given module name.
ModuleFile *lookupByModuleName(StringRef ModName) const;
- /// \brief Returns the module associated with the given module file.
+ /// Returns the module associated with the given module file.
ModuleFile *lookup(const FileEntry *File) const;
- /// \brief Returns the in-memory (virtual file) buffer with the given name
+ /// Returns the in-memory (virtual file) buffer with the given name
std::unique_ptr<llvm::MemoryBuffer> lookupBuffer(StringRef Name);
- /// \brief Number of modules loaded
+ /// Number of modules loaded
unsigned size() const { return Chain.size(); }
- /// \brief The result of attempting to add a new module.
+ /// The result of attempting to add a new module.
enum AddModuleResult {
- /// \brief The module file had already been loaded.
+ /// The module file had already been loaded.
AlreadyLoaded,
- /// \brief The module file was just loaded in response to this call.
+ /// The module file was just loaded in response to this call.
NewlyLoaded,
- /// \brief The module file is missing.
+ /// The module file is missing.
Missing,
- /// \brief The module file is out-of-date.
+ /// The module file is out-of-date.
OutOfDate
};
using ASTFileSignatureReader = ASTFileSignature (*)(StringRef);
- /// \brief Attempts to create a new module and add it to the list of known
+ /// Attempts to create a new module and add it to the list of known
/// modules.
///
/// \param FileName The file name of the module to be loaded.
@@ -255,23 +255,23 @@ public:
ModuleFile *&Module,
std::string &ErrorStr);
- /// \brief Remove the modules starting from First (to the end).
+ /// Remove the modules starting from First (to the end).
void removeModules(ModuleIterator First,
llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
ModuleMap *modMap);
- /// \brief Add an in-memory buffer the list of known buffers
+ /// Add an in-memory buffer the list of known buffers
void addInMemoryBuffer(StringRef FileName,
std::unique_ptr<llvm::MemoryBuffer> Buffer);
- /// \brief Set the global module index.
+ /// Set the global module index.
void setGlobalIndex(GlobalModuleIndex *Index);
- /// \brief Notification from the AST reader that the given module file
+ /// Notification from the AST reader that the given module file
/// has been "accepted", and will not (can not) be unloaded.
void moduleFileAccepted(ModuleFile *MF);
- /// \brief Visit each of the modules.
+ /// Visit each of the modules.
///
/// This routine visits each of the modules, starting with the
/// "root" modules that no other loaded modules depend on, and
@@ -293,7 +293,7 @@ public:
void visit(llvm::function_ref<bool(ModuleFile &M)> Visitor,
llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit = nullptr);
- /// \brief Attempt to resolve the given module file name to a file entry.
+ /// Attempt to resolve the given module file name to a file entry.
///
/// \param FileName The name of the module file.
///
@@ -315,7 +315,7 @@ public:
time_t ExpectedModTime,
const FileEntry *&File);
- /// \brief View the graphviz representation of the module graph.
+ /// View the graphviz representation of the module graph.
void viewGraph();
MemoryBufferCache &getPCMCache() const { return *PCMCache; }
diff --git a/include/clang/StaticAnalyzer/Checkers/CMakeLists.txt b/include/clang/StaticAnalyzer/Checkers/CMakeLists.txt
index 37dd9e8482968..236647c534851 100644
--- a/include/clang/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/include/clang/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -1,4 +1,3 @@
clang_tablegen(Checkers.inc -gen-clang-sa-checkers
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../../
SOURCE Checkers.td
TARGET ClangSACheckers)
diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td
index e510e84e938af..ab0e4af1361b9 100644
--- a/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-include "clang/StaticAnalyzer/Checkers/CheckerBase.td"
+include "CheckerBase.td"
//===----------------------------------------------------------------------===//
// Packages.
@@ -86,7 +86,7 @@ def LLVM : Package<"llvm">;
// The APIModeling package is for checkers that model APIs and don't perform
// any diagnostics. These checkers are always turned on; this package is
-// intended for API modeling that is not controlled by the the target triple.
+// intended for API modeling that is not controlled by the target triple.
def APIModeling : Package<"apiModeling">, Hidden;
def GoogleAPIModeling : Package<"google">, InPackage<APIModeling>;
@@ -218,6 +218,14 @@ def NullableReturnedFromNonnullChecker : Checker<"NullableReturnedFromNonnull">,
} // end "nullability"
+let ParentPackage = APIModeling in {
+
+def TrustNonnullChecker : Checker<"TrustNonnull">,
+ HelpText<"Trust that returns from framework methods annotated with _Nonnull are not null">,
+ DescFile<"TrustNonnullChecker.cpp">;
+
+}
+
//===----------------------------------------------------------------------===//
// Evaluate "builtin" functions.
//===----------------------------------------------------------------------===//
@@ -297,6 +305,10 @@ def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">,
"destructor in their base class">,
DescFile<"DeleteWithNonVirtualDtorChecker.cpp">;
+def InnerPointerChecker : Checker<"InnerPointer">,
+ HelpText<"Check for inner pointers of C++ containers used after re/deallocation">,
+ DescFile<"InnerPointerChecker.cpp">;
+
def IteratorRangeChecker : Checker<"IteratorRange">,
HelpText<"Check for iterators used outside their valid ranges">,
DescFile<"IteratorChecker.cpp">;
@@ -306,6 +318,10 @@ def MisusedMovedObjectChecker: Checker<"MisusedMovedObject">,
"object will be reported">,
DescFile<"MisusedMovedObjectChecker.cpp">;
+def UninitializedObjectChecker: Checker<"UninitializedObject">,
+ HelpText<"Reports uninitialized fields after object construction">,
+ DescFile<"UninitializedObjectChecker.cpp">;
+
} // end: "alpha.cplusplus"
@@ -365,6 +381,15 @@ def PaddingChecker : Checker<"Padding">,
//===----------------------------------------------------------------------===//
let ParentPackage = InsecureAPI in {
+ def bcmp : Checker<"bcmp">,
+ HelpText<"Warn on uses of the 'bcmp' function">,
+ DescFile<"CheckSecuritySyntaxOnly.cpp">;
+ def bcopy : Checker<"bcopy">,
+ HelpText<"Warn on uses of the 'bcopy' function">,
+ DescFile<"CheckSecuritySyntaxOnly.cpp">;
+ def bzero : Checker<"bzero">,
+ HelpText<"Warn on uses of the 'bzero' function">,
+ DescFile<"CheckSecuritySyntaxOnly.cpp">;
def gets : Checker<"gets">,
HelpText<"Warn on uses of the 'gets' function">,
DescFile<"CheckSecuritySyntaxOnly.cpp">;
@@ -414,6 +439,13 @@ def MallocOverflowSecurityChecker : Checker<"MallocOverflow">,
HelpText<"Check for overflows in the arguments to malloc()">,
DescFile<"MallocOverflowSecurityChecker.cpp">;
+// Operating systems specific PROT_READ/PROT_WRITE values is not implemented,
+// the defaults are correct for several common operating systems though,
+// but may need to be overridden via the related analyzer-config flags.
+def MmapWriteExecChecker : Checker<"MmapWriteExec">,
+ HelpText<"Warn on mmap() calls that are both writable and executable">,
+ DescFile<"MmapWriteExecChecker.cpp">;
+
} // end "alpha.security"
//===----------------------------------------------------------------------===//
@@ -536,6 +568,10 @@ def ObjCPropertyChecker : Checker<"ObjCProperty">,
let ParentPackage = Cocoa in {
+def RunLoopAutoreleaseLeakChecker : Checker<"RunLoopAutoreleaseLeak">,
+ HelpText<"Check for leaked memory in autorelease pools that will never be drained">,
+ DescFile<"RunLoopAutoreleaseLeakChecker.cpp">;
+
def ObjCAtSyncChecker : Checker<"AtSync">,
HelpText<"Check for nil pointers used as mutexes for @synchronized">,
DescFile<"ObjCAtSyncChecker.cpp">;
@@ -601,8 +637,18 @@ def ObjCSuperDeallocChecker : Checker<"SuperDealloc">,
HelpText<"Warn about improper use of '[super dealloc]' in Objective-C">,
DescFile<"ObjCSuperDeallocChecker.cpp">;
+def AutoreleaseWriteChecker : Checker<"AutoreleaseWrite">,
+ HelpText<"Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C">,
+ DescFile<"ObjCAutoreleaseWriteChecker.cpp">;
} // end "osx.cocoa"
+let ParentPackage = Performance in {
+
+def GCDAntipattern : Checker<"GCDAntipattern">,
+ HelpText<"Check for performance anti-patterns when using Grand Central Dispatch">,
+ DescFile<"GCDAntipatternChecker.cpp">;
+} // end "optin.performance"
+
let ParentPackage = CocoaAlpha in {
def InstanceVariableInvalidation : Checker<"InstanceVariableInvalidation">,
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index ce50cc582d1e0..9d292cfddb0c8 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -1,4 +1,4 @@
-//===--- AnalyzerOptions.h - Analysis Engine Options ------------*- C++ -*-===//
+//===- AnalyzerOptions.h - Analysis Engine Options --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,18 +19,18 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include <string>
+#include <utility>
#include <vector>
namespace clang {
-class ASTConsumer;
-class DiagnosticsEngine;
-class Preprocessor;
-class LangOptions;
namespace ento {
+
class CheckerBase;
-}
+
+} // namespace ento
/// Analysis - Set of available source code analyses.
enum Analyses {
@@ -76,7 +76,7 @@ enum AnalysisInliningMode {
NumInliningModes
};
-/// \brief Describes the different kinds of C++ member functions which can be
+/// Describes the different kinds of C++ member functions which can be
/// considered for inlining by the analyzer.
///
/// These options are cumulative; enabling one kind of member function will
@@ -100,7 +100,7 @@ enum CXXInlineableMemberKind {
CIMK_Destructors
};
-/// \brief Describes the different modes of inter-procedural analysis.
+/// Describes the different modes of inter-procedural analysis.
enum IPAKind {
IPAK_NotSet = 0,
@@ -123,28 +123,31 @@ enum IPAKind {
class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
public:
- typedef llvm::StringMap<std::string> ConfigTable;
+ using ConfigTable = llvm::StringMap<std::string>;
static std::vector<StringRef>
getRegisteredCheckers(bool IncludeExperimental = false);
- /// \brief Pair of checker name and enable/disable.
- std::vector<std::pair<std::string, bool> > CheckersControlList;
+ /// Pair of checker name and enable/disable.
+ std::vector<std::pair<std::string, bool>> CheckersControlList;
- /// \brief A key-value table of use-specified configuration values.
+ /// A key-value table of use-specified configuration values.
ConfigTable Config;
- AnalysisStores AnalysisStoreOpt;
- AnalysisConstraints AnalysisConstraintsOpt;
- AnalysisDiagClients AnalysisDiagOpt;
- AnalysisPurgeMode AnalysisPurgeOpt;
+ AnalysisStores AnalysisStoreOpt = RegionStoreModel;
+ AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel;
+ AnalysisDiagClients AnalysisDiagOpt = PD_HTML;
+ AnalysisPurgeMode AnalysisPurgeOpt = PurgeStmt;
std::string AnalyzeSpecificFunction;
+
+ /// Store full compiler invocation for reproducible instructions in the
+ /// generated report.
+ std::string FullCompilerInvocation;
- /// \brief The maximum number of times the analyzer visits a block.
+ /// The maximum number of times the analyzer visits a block.
unsigned maxBlockVisitOnPath;
-
- /// \brief Disable all analyzer checks.
+ /// Disable all analyzer checks.
///
/// This flag allows one to disable analyzer checks on the code processed by
/// the given analysis consumer. Note, the code will get parsed and the
@@ -157,7 +160,7 @@ public:
unsigned AnalyzerDisplayProgress : 1;
unsigned AnalyzeNestedBlocks : 1;
- /// \brief The flag regulates if we should eagerly assume evaluations of
+ /// The flag regulates if we should eagerly assume evaluations of
/// conditionals, thus, bifurcating the path.
///
/// This flag indicates how the engine should handle expressions such as: 'x =
@@ -174,22 +177,36 @@ public:
unsigned UnoptimizedCFG : 1;
unsigned PrintStats : 1;
- /// \brief Do not re-analyze paths leading to exhausted nodes with a different
+ /// Do not re-analyze paths leading to exhausted nodes with a different
/// strategy. We get better code coverage when retry is enabled.
unsigned NoRetryExhausted : 1;
- /// \brief The inlining stack depth limit.
- unsigned InlineMaxStackDepth;
+ /// The inlining stack depth limit.
+ // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
+ unsigned InlineMaxStackDepth = 5;
- /// \brief The mode of function selection used during inlining.
- AnalysisInliningMode InliningMode;
+ /// The mode of function selection used during inlining.
+ AnalysisInliningMode InliningMode = NoRedundancy;
+
+ enum class ExplorationStrategyKind {
+ DFS,
+ BFS,
+ UnexploredFirst,
+ UnexploredFirstQueue,
+ BFSBlockDFSContents,
+ NotSet
+ };
private:
- /// \brief Describes the kinds for high-level analyzer mode.
+ ExplorationStrategyKind ExplorationStrategy = ExplorationStrategyKind::NotSet;
+
+ /// Describes the kinds for high-level analyzer mode.
enum UserModeKind {
UMK_NotSet = 0,
+
/// Perform shallow but fast analyzes.
UMK_Shallow = 1,
+
/// Perform deep analyzes.
UMK_Deep = 2
};
@@ -197,10 +214,10 @@ private:
/// Controls the high-level analyzer mode, which influences the default
/// settings for some of the lower-level config options (such as IPAMode).
/// \sa getUserMode
- UserModeKind UserMode;
+ UserModeKind UserMode = UMK_NotSet;
/// Controls the mode of inter-procedural analysis.
- IPAKind IPAMode;
+ IPAKind IPAMode = IPAK_NotSet;
/// Controls which C++ member functions will be considered for inlining.
CXXInlineableMemberKind CXXMemberInliningMode;
@@ -217,9 +234,15 @@ private:
/// \sa IncludeLoopExitInCFG
Optional<bool> IncludeLoopExitInCFG;
+ /// \sa IncludeRichConstructorsInCFG
+ Optional<bool> IncludeRichConstructorsInCFG;
+
/// \sa mayInlineCXXStandardLibrary
Optional<bool> InlineCXXStandardLibrary;
+ /// \sa includeScopesInCFG
+ Optional<bool> IncludeScopesInCFG;
+
/// \sa mayInlineTemplateFunctions
Optional<bool> InlineTemplateFunctions;
@@ -232,6 +255,9 @@ private:
/// \sa mayInlineCXXSharedPtrDtor
Optional<bool> InlineCXXSharedPtrDtor;
+ /// \sa mayInlineCXXTemporaryDtors
+ Optional<bool> InlineCXXTemporaryDtors;
+
/// \sa mayInlineObjCMethod
Optional<bool> ObjCInliningMode;
@@ -254,15 +280,23 @@ private:
/// \sa shouldSuppressFromCXXStandardLibrary
Optional<bool> SuppressFromCXXStandardLibrary;
+ /// \sa shouldCrosscheckWithZ3
+ Optional<bool> CrosscheckWithZ3;
+
/// \sa reportIssuesInMainSourceFile
Optional<bool> ReportIssuesInMainSourceFile;
/// \sa StableReportFilename
Optional<bool> StableReportFilename;
+ Optional<bool> SerializeStats;
+
/// \sa getGraphTrimInterval
Optional<unsigned> GraphTrimInterval;
+ /// \sa getMaxSymbolComplexity
+ Optional<unsigned> MaxSymbolComplexity;
+
/// \sa getMaxTimesInlineLarge
Optional<unsigned> MaxTimesInlineLarge;
@@ -284,6 +318,22 @@ private:
/// \sa shouldDisplayNotesAsEvents
Optional<bool> DisplayNotesAsEvents;
+ /// \sa shouldAggressivelySimplifyBinaryOperation
+ Optional<bool> AggressiveBinaryOperationSimplification;
+
+ /// \sa getCTUDir
+ Optional<StringRef> CTUDir;
+
+ /// \sa getCTUIndexName
+ Optional<StringRef> CTUIndexName;
+
+ /// \sa naiveCTUEnabled
+ Optional<bool> NaiveCTU;
+
+ /// \sa shouldElideConstructors
+ Optional<bool> ElideConstructors;
+
+
/// A helper function that retrieves option for a given full-qualified
/// checker name.
/// Options for checkers can be specified via 'analyzer-config' command-line
@@ -311,6 +361,15 @@ private:
bool SearchInParents = false);
public:
+ AnalyzerOptions()
+ : DisableAllChecks(false), ShowCheckerHelp(false),
+ ShowEnabledCheckerList(false), AnalyzeAll(false),
+ AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false),
+ eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
+ visualizeExplodedGraphWithGraphViz(false),
+ visualizeExplodedGraphWithUbiGraph(false), UnoptimizedCFG(false),
+ PrintStats(false), NoRetryExhausted(false), CXXMemberInliningMode() {}
+
/// Interprets an option's string value as a boolean. The "true" string is
/// interpreted as true and the "false" string is interpreted as false.
///
@@ -320,7 +379,7 @@ public:
/// specified.
/// @param [in] C The optional checker parameter that can be used to restrict
/// the search to the options of this particular checker (and its parents
- /// dependening on search mode).
+ /// depending on search mode).
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
@@ -338,7 +397,7 @@ public:
/// specified.
/// @param [in] C The optional checker parameter that can be used to restrict
/// the search to the options of this particular checker (and its parents
- /// dependening on search mode).
+ /// depending on search mode).
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
@@ -355,7 +414,7 @@ public:
/// specified.
/// @param [in] C The optional checker parameter that can be used to restrict
/// the search to the options of this particular checker (and its parents
- /// dependening on search mode).
+ /// depending on search mode).
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
@@ -372,7 +431,7 @@ public:
/// specified.
/// @param [in] C The optional checker parameter that can be used to restrict
/// the search to the options of this particular checker (and its parents
- /// dependening on search mode).
+ /// depending on search mode).
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
@@ -381,12 +440,14 @@ public:
const ento::CheckerBase *C = nullptr,
bool SearchInParents = false);
- /// \brief Retrieves and sets the UserMode. This is a high-level option,
+ /// Retrieves and sets the UserMode. This is a high-level option,
/// which is used to set other low-level options. It is not accessible
/// outside of AnalyzerOptions.
UserModeKind getUserMode();
- /// \brief Returns the inter-procedural analysis mode.
+ ExplorationStrategyKind getExplorationStrategy();
+
+ /// Returns the inter-procedural analysis mode.
IPAKind getIPAMode();
/// Returns the option controlling which C++ member functions will be
@@ -428,6 +489,19 @@ public:
/// the values "true" and "false".
bool includeLoopExitInCFG();
+ /// Returns whether or not construction site information should be included
+ /// in the CFG C++ constructor elements.
+ ///
+ /// This is controlled by the 'cfg-rich-constructors' config options,
+ /// which accepts the values "true" and "false".
+ bool includeRichConstructorsInCFG();
+
+ /// Returns whether or not scope information should be included in the CFG.
+ ///
+ /// This is controlled by the 'cfg-scope-info' config option, which accepts
+ /// the values "true" and "false".
+ bool includeScopesInCFG();
+
/// Returns whether or not C++ standard library functions may be considered
/// for inlining.
///
@@ -464,6 +538,17 @@ public:
/// accepts the values "true" and "false".
bool mayInlineCXXSharedPtrDtor();
+ /// Returns true if C++ temporary destructors should be inlined during
+ /// analysis.
+ ///
+ /// If temporary destructors are disabled in the CFG via the
+ /// 'cfg-temporary-dtors' option, temporary destructors would not be
+ /// inlined anyway.
+ ///
+ /// This is controlled by the 'c++-temp-dtor-inlining' config option, which
+ /// accepts the values "true" and "false".
+ bool mayInlineCXXTemporaryDtors();
+
/// Returns whether or not paths that go through null returns should be
/// suppressed.
///
@@ -499,6 +584,13 @@ public:
/// which accepts the values "true" and "false".
bool shouldSuppressFromCXXStandardLibrary();
+ /// Returns whether bug reports should be crosschecked with the Z3
+ /// constraint manager backend.
+ ///
+ /// This is controlled by the 'crosscheck-with-z3' config option,
+ /// which accepts the values "true" and "false".
+ bool shouldCrosscheckWithZ3();
+
/// Returns whether or not the diagnostic report should be always reported
/// in the main source file and not the headers.
///
@@ -512,6 +604,14 @@ public:
/// which accepts the values "true" and "false". Default = false
bool shouldWriteStableReportFilename();
+ /// \return Whether the analyzer should
+ /// serialize statistics to plist output.
+ /// Statistics would be serialized in JSON format inside the main dictionary
+ /// under the \c statistics key.
+ /// Available only if compiled in assert mode or with LLVM statistics
+ /// explicitly enabled.
+ bool shouldSerializeStats();
+
/// Returns whether irrelevant parts of a bug report path should be pruned
/// out of the final output.
///
@@ -546,6 +646,11 @@ public:
/// node reclamation, set the option to "0".
unsigned getGraphTrimInterval();
+ /// Returns the maximum complexity of symbolic constraint (50 by default).
+ ///
+ /// This is controlled by "-analyzer-config max-symbol-complexity" option.
+ unsigned getMaxSymbolComplexity();
+
/// Returns the maximum times a large function could be inlined.
///
/// This is controlled by the 'max-times-inline-large' config option.
@@ -585,36 +690,41 @@ public:
/// to false when unset.
bool shouldDisplayNotesAsEvents();
-public:
- AnalyzerOptions() :
- AnalysisStoreOpt(RegionStoreModel),
- AnalysisConstraintsOpt(RangeConstraintsModel),
- AnalysisDiagOpt(PD_HTML),
- AnalysisPurgeOpt(PurgeStmt),
- DisableAllChecks(0),
- ShowCheckerHelp(0),
- ShowEnabledCheckerList(0),
- AnalyzeAll(0),
- AnalyzerDisplayProgress(0),
- AnalyzeNestedBlocks(0),
- eagerlyAssumeBinOpBifurcation(0),
- TrimGraph(0),
- visualizeExplodedGraphWithGraphViz(0),
- visualizeExplodedGraphWithUbiGraph(0),
- UnoptimizedCFG(0),
- PrintStats(0),
- NoRetryExhausted(0),
- // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
- InlineMaxStackDepth(5),
- InliningMode(NoRedundancy),
- UserMode(UMK_NotSet),
- IPAMode(IPAK_NotSet),
- CXXMemberInliningMode() {}
-
+ /// Returns true if SValBuilder should rearrange comparisons and additive
+ /// operations of symbolic expressions which consist of a sum of a symbol and
+ /// a concrete integer into the format where symbols are on the left-hand
+ /// side and the integer is on the right. This is only done if both symbols
+ /// and both concrete integers are signed, greater than or equal to the
+ /// quarter of the minimum value of the type and less than or equal to the
+ /// quarter of the maximum value of that type.
+ ///
+ /// A + n <OP> B + m becomes A - B <OP> m - n, where A and B symbolic,
+ /// n and m are integers. <OP> is any of '==', '!=', '<', '<=', '>', '>=',
+ /// '+' or '-'. The rearrangement also happens with '-' instead of '+' on
+ // either or both side and also if any or both integers are missing.
+ bool shouldAggressivelySimplifyBinaryOperation();
+
+ /// Returns the directory containing the CTU related files.
+ StringRef getCTUDir();
+
+ /// Returns the name of the file containing the CTU index of functions.
+ StringRef getCTUIndexName();
+
+ /// Returns true when naive cross translation unit analysis is enabled.
+ /// This is an experimental feature to inline functions from another
+ /// translation units.
+ bool naiveCTUEnabled();
+
+ /// Returns true if elidable C++ copy-constructors and move-constructors
+ /// should be actually elided during analysis. Both behaviors are allowed
+ /// by the C++ standard, and the analyzer, like CodeGen, defaults to eliding.
+ /// Starting with C++17 some elisions become mandatory, and in these cases
+ /// the option will be ignored.
+ bool shouldElideConstructors();
};
-typedef IntrusiveRefCntPtr<AnalyzerOptions> AnalyzerOptionsRef;
+using AnalyzerOptionsRef = IntrusiveRefCntPtr<AnalyzerOptions>;
-}
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index cd1355d03b639..111e1d1e8e20a 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -1,4 +1,4 @@
-//===--- BugReporter.h - Generate PathDiagnostics --------------*- C++ -*-===//
+//===- BugReporter.h - Generate PathDiagnostics -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,78 +15,101 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H
#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableSet.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/iterator_range.h"
+#include <cassert>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
namespace clang {
+class AnalyzerOptions;
class ASTContext;
+class Decl;
class DiagnosticsEngine;
+class LocationContext;
+class SourceManager;
class Stmt;
-class ParentMap;
namespace ento {
-class PathDiagnostic;
-class ExplodedNode;
+class BugType;
+class CheckerBase;
class ExplodedGraph;
-class BugReport;
-class BugReporter;
-class BugReporterContext;
+class ExplodedNode;
class ExprEngine;
-class BugType;
+class MemRegion;
+class SValBuilder;
//===----------------------------------------------------------------------===//
// Interface for individual bug reports.
//===----------------------------------------------------------------------===//
+/// A mapping from diagnostic consumers to the diagnostics they should
+/// consume.
+using DiagnosticForConsumerMapTy =
+ llvm::DenseMap<PathDiagnosticConsumer *, std::unique_ptr<PathDiagnostic>>;
+
/// This class provides an interface through which checkers can create
/// individual bug reports.
class BugReport : public llvm::ilist_node<BugReport> {
public:
class NodeResolver {
virtual void anchor();
+
public:
- virtual ~NodeResolver() {}
+ virtual ~NodeResolver() = default;
+
virtual const ExplodedNode*
getOriginalNode(const ExplodedNode *N) = 0;
};
- typedef const SourceRange *ranges_iterator;
- typedef SmallVector<std::unique_ptr<BugReporterVisitor>, 8> VisitorList;
- typedef VisitorList::iterator visitor_iterator;
- typedef SmallVector<StringRef, 2> ExtraTextList;
- typedef SmallVector<std::shared_ptr<PathDiagnosticNotePiece>, 4> NoteList;
+ using ranges_iterator = const SourceRange *;
+ using VisitorList = SmallVector<std::unique_ptr<BugReporterVisitor>, 8>;
+ using visitor_iterator = VisitorList::iterator;
+ using ExtraTextList = SmallVector<StringRef, 2>;
+ using NoteList = SmallVector<std::shared_ptr<PathDiagnosticNotePiece>, 4>;
protected:
- friend class BugReporter;
friend class BugReportEquivClass;
+ friend class BugReporter;
BugType& BT;
- const Decl *DeclWithIssue;
+ const Decl *DeclWithIssue = nullptr;
std::string ShortDescription;
std::string Description;
PathDiagnosticLocation Location;
PathDiagnosticLocation UniqueingLocation;
const Decl *UniqueingDecl;
- const ExplodedNode *ErrorNode;
+ const ExplodedNode *ErrorNode = nullptr;
SmallVector<SourceRange, 4> Ranges;
ExtraTextList ExtraText;
NoteList Notes;
- typedef llvm::DenseSet<SymbolRef> Symbols;
- typedef llvm::DenseSet<const MemRegion *> Regions;
+ using Symbols = llvm::DenseSet<SymbolRef>;
+ using Regions = llvm::DenseSet<const MemRegion *>;
/// A (stack of) a set of symbols that are registered with this
/// report as being "interesting", and thus used to help decide which
@@ -113,20 +136,16 @@ protected:
/// Used for ensuring the visitors are only added once.
llvm::FoldingSet<BugReporterVisitor> CallbacksSet;
- /// Used for clients to tell if the report's configuration has changed
- /// since the last time they checked.
- unsigned ConfigurationChangeToken;
-
/// When set, this flag disables all callstack pruning from a diagnostic
/// path. This is useful for some reports that want maximum fidelty
/// when reporting an issue.
- bool DoNotPrunePath;
+ bool DoNotPrunePath = false;
/// Used to track unique reasons why a bug report might be invalid.
///
/// \sa markInvalid
/// \sa removeInvalidation
- typedef std::pair<const void *, const void *> InvalidationRecord;
+ using InvalidationRecord = std::pair<const void *, const void *>;
/// If non-empty, this bug report is likely a false positive and should not be
/// shown to the user.
@@ -146,20 +165,17 @@ private:
public:
BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode)
- : BT(bt), DeclWithIssue(nullptr), Description(desc), ErrorNode(errornode),
- ConfigurationChangeToken(0), DoNotPrunePath(false) {}
+ : BT(bt), Description(desc), ErrorNode(errornode) {}
BugReport(BugType& bt, StringRef shortDesc, StringRef desc,
const ExplodedNode *errornode)
- : BT(bt), DeclWithIssue(nullptr), ShortDescription(shortDesc),
- Description(desc), ErrorNode(errornode), ConfigurationChangeToken(0),
- DoNotPrunePath(false) {}
+ : BT(bt), ShortDescription(shortDesc), Description(desc),
+ ErrorNode(errornode) {}
BugReport(BugType &bt, StringRef desc, PathDiagnosticLocation l)
- : BT(bt), DeclWithIssue(nullptr), Description(desc), Location(l),
- ErrorNode(nullptr), ConfigurationChangeToken(0), DoNotPrunePath(false) {}
+ : BT(bt), Description(desc), Location(l) {}
- /// \brief Create a BugReport with a custom uniqueing location.
+ /// Create a BugReport with a custom uniqueing location.
///
/// The reports that have the same report location, description, bug type, and
/// ranges are uniqued - only one of the equivalent reports will be presented
@@ -168,18 +184,15 @@ public:
/// the allocation site, rather then the location where the bug is reported.
BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode,
PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique)
- : BT(bt), DeclWithIssue(nullptr), Description(desc),
- UniqueingLocation(LocationToUnique),
- UniqueingDecl(DeclToUnique),
- ErrorNode(errornode), ConfigurationChangeToken(0),
- DoNotPrunePath(false) {}
+ : BT(bt), Description(desc), UniqueingLocation(LocationToUnique),
+ UniqueingDecl(DeclToUnique), ErrorNode(errornode) {}
virtual ~BugReport();
const BugType& getBugType() const { return BT; }
BugType& getBugType() { return BT; }
- /// \brief True when the report has an execution path associated with it.
+ /// True when the report has an execution path associated with it.
///
/// A report is said to be path-sensitive if it was thrown against a
/// particular exploded node in the path-sensitive analysis graph.
@@ -218,10 +231,6 @@ public:
bool isInteresting(SVal V);
bool isInteresting(const LocationContext *LC);
- unsigned getConfigurationChangeToken() const {
- return ConfigurationChangeToken;
- }
-
/// Returns whether or not this report should be considered valid.
///
/// Invalid reports are those that have been classified as likely false
@@ -242,13 +251,6 @@ public:
void markInvalid(const void *Tag, const void *Data) {
Invalidations.insert(std::make_pair(Tag, Data));
}
-
- /// Reverses the effects of a previous invalidation.
- ///
- /// \sa markInvalid
- void removeInvalidation(const void *Tag, const void *Data) {
- Invalidations.erase(std::make_pair(Tag, Data));
- }
/// Return the canonical declaration, be it a method or class, where
/// this issue semantically occurred.
@@ -286,7 +288,7 @@ public:
return Notes;
}
- /// \brief This allows for addition of meta data to the diagnostic.
+ /// This allows for addition of meta data to the diagnostic.
///
/// Currently, only the HTMLDiagnosticClient knows how to display it.
void addExtraText(StringRef S) {
@@ -297,26 +299,26 @@ public:
return ExtraText;
}
- /// \brief Return the "definitive" location of the reported bug.
+ /// Return the "definitive" location of the reported bug.
///
/// While a bug can span an entire path, usually there is a specific
/// location that can be used to identify where the key issue occurred.
/// This location is used by clients rendering diagnostics.
virtual PathDiagnosticLocation getLocation(const SourceManager &SM) const;
- /// \brief Get the location on which the report should be uniqued.
+ /// Get the location on which the report should be uniqued.
PathDiagnosticLocation getUniqueingLocation() const {
return UniqueingLocation;
}
- /// \brief Get the declaration containing the uniqueing location.
+ /// Get the declaration containing the uniqueing location.
const Decl *getUniqueingDecl() const {
return UniqueingDecl;
}
const Stmt *getStmt() const;
- /// \brief Add a range to a bug report.
+ /// Add a range to a bug report.
///
/// Ranges are used to highlight regions of interest in the source code.
/// They should be at the same source code line as the BugReport location.
@@ -329,10 +331,10 @@ public:
Ranges.push_back(R);
}
- /// \brief Get the SourceRanges associated with the report.
+ /// Get the SourceRanges associated with the report.
virtual llvm::iterator_range<ranges_iterator> getRanges();
- /// \brief Add custom or predefined bug report visitors to this report.
+ /// Add custom or predefined bug report visitors to this report.
///
/// The visitors should be used when the default trace is not sufficient.
/// For example, they allow constructing a more elaborate trace.
@@ -341,6 +343,9 @@ public:
/// registerVarDeclsLastStore().
void addVisitor(std::unique_ptr<BugReporterVisitor> visitor);
+ /// Remove all visitors attached to this bug report.
+ void clearVisitors();
+
/// Iterators through the custom diagnostic visitors.
visitor_iterator visitor_begin() { return Callbacks.begin(); }
visitor_iterator visitor_end() { return Callbacks.end(); }
@@ -356,10 +361,11 @@ public:
//===----------------------------------------------------------------------===//
class BugReportEquivClass : public llvm::FoldingSetNode {
+ friend class BugReporter;
+
/// List of *owned* BugReport objects.
llvm::ilist<BugReport> Reports;
- friend class BugReporter;
void AddReport(std::unique_ptr<BugReport> R) {
Reports.push_back(R.release());
}
@@ -373,8 +379,8 @@ public:
Reports.front().Profile(ID);
}
- typedef llvm::ilist<BugReport>::iterator iterator;
- typedef llvm::ilist<BugReport>::const_iterator const_iterator;
+ using iterator = llvm::ilist<BugReport>::iterator;
+ using const_iterator = llvm::ilist<BugReport>::const_iterator;
iterator begin() { return Reports.begin(); }
iterator end() { return Reports.end(); }
@@ -390,22 +396,26 @@ public:
class BugReporterData {
public:
virtual ~BugReporterData();
+
virtual DiagnosticsEngine& getDiagnostic() = 0;
virtual ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() = 0;
virtual ASTContext &getASTContext() = 0;
- virtual SourceManager& getSourceManager() = 0;
- virtual AnalyzerOptions& getAnalyzerOptions() = 0;
+ virtual SourceManager &getSourceManager() = 0;
+ virtual AnalyzerOptions &getAnalyzerOptions() = 0;
};
/// BugReporter is a utility class for generating PathDiagnostics for analysis.
/// It collects the BugReports and BugTypes and knows how to generate
/// and flush the corresponding diagnostics.
+///
+/// The base class is used for generating path-insensitive
class BugReporter {
public:
enum Kind { BaseBRKind, GRBugReporterKind };
private:
- typedef llvm::ImmutableSet<BugType*> BugTypesTy;
+ using BugTypesTy = llvm::ImmutableSet<BugType *>;
+
BugTypesTy::Factory F;
BugTypesTy BugTypes;
@@ -415,27 +425,28 @@ private:
/// Generate and flush the diagnostics for the given bug report.
void FlushReport(BugReportEquivClass& EQ);
- /// Generate and flush the diagnostics for the given bug report
- /// and PathDiagnosticConsumer.
- void FlushReport(BugReport *exampleReport,
- PathDiagnosticConsumer &PD,
- ArrayRef<BugReport*> BugReports);
+ /// Generate the diagnostics for the given bug report.
+ std::unique_ptr<DiagnosticForConsumerMapTy>
+ generateDiagnosticForConsumerMap(BugReport *exampleReport,
+ ArrayRef<PathDiagnosticConsumer *> consumers,
+ ArrayRef<BugReport *> bugReports);
/// The set of bug reports tracked by the BugReporter.
llvm::FoldingSet<BugReportEquivClass> EQClasses;
+
/// A vector of BugReports for tracking the allocated pointers and cleanup.
std::vector<BugReportEquivClass *> EQClassesVector;
protected:
- BugReporter(BugReporterData& d, Kind k) : BugTypes(F.getEmptySet()), kind(k),
- D(d) {}
+ BugReporter(BugReporterData& d, Kind k)
+ : BugTypes(F.getEmptySet()), kind(k), D(d) {}
public:
- BugReporter(BugReporterData& d) : BugTypes(F.getEmptySet()), kind(BaseBRKind),
- D(d) {}
+ BugReporter(BugReporterData& d)
+ : BugTypes(F.getEmptySet()), kind(BaseBRKind), D(d) {}
virtual ~BugReporter();
- /// \brief Generate and flush diagnostics for all bug reports.
+ /// Generate and flush diagnostics for all bug reports.
void FlushReports();
Kind getKind() const { return kind; }
@@ -448,33 +459,31 @@ public:
return D.getPathDiagnosticConsumers();
}
- /// \brief Iterator over the set of BugTypes tracked by the BugReporter.
- typedef BugTypesTy::iterator iterator;
+ /// Iterator over the set of BugTypes tracked by the BugReporter.
+ using iterator = BugTypesTy::iterator;
iterator begin() { return BugTypes.begin(); }
iterator end() { return BugTypes.end(); }
- /// \brief Iterator over the set of BugReports tracked by the BugReporter.
- typedef llvm::FoldingSet<BugReportEquivClass>::iterator EQClasses_iterator;
+ /// Iterator over the set of BugReports tracked by the BugReporter.
+ using EQClasses_iterator = llvm::FoldingSet<BugReportEquivClass>::iterator;
EQClasses_iterator EQClasses_begin() { return EQClasses.begin(); }
EQClasses_iterator EQClasses_end() { return EQClasses.end(); }
ASTContext &getContext() { return D.getASTContext(); }
- SourceManager& getSourceManager() { return D.getSourceManager(); }
+ SourceManager &getSourceManager() { return D.getSourceManager(); }
- AnalyzerOptions& getAnalyzerOptions() { return D.getAnalyzerOptions(); }
+ AnalyzerOptions &getAnalyzerOptions() { return D.getAnalyzerOptions(); }
- virtual bool generatePathDiagnostic(PathDiagnostic& pathDiagnostic,
- PathDiagnosticConsumer &PC,
- ArrayRef<BugReport *> &bugReports) {
- return true;
+ virtual std::unique_ptr<DiagnosticForConsumerMapTy>
+ generatePathDiagnostics(ArrayRef<PathDiagnosticConsumer *> consumers,
+ ArrayRef<BugReport *> &bugReports) {
+ return {};
}
- bool RemoveUnneededCalls(PathPieces &pieces, BugReport *R);
-
void Register(BugType *BT);
- /// \brief Add the given report to the set of reports tracked by BugReporter.
+ /// Add the given report to the set of reports tracked by BugReporter.
///
/// The reports are usually generated by the checkers. Further, they are
/// folded based on the profile value, which is done to coalesce similar
@@ -494,25 +503,22 @@ public:
private:
llvm::StringMap<BugType *> StrBugTypes;
- /// \brief Returns a BugType that is associated with the given name and
+ /// Returns a BugType that is associated with the given name and
/// category.
BugType *getBugTypeForName(CheckName CheckName, StringRef name,
StringRef category);
};
-// FIXME: Get rid of GRBugReporter. It's the wrong abstraction.
+/// GRBugReporter is used for generating path-sensitive reports.
class GRBugReporter : public BugReporter {
ExprEngine& Eng;
+
public:
GRBugReporter(BugReporterData& d, ExprEngine& eng)
- : BugReporter(d, GRBugReporterKind), Eng(eng) {}
+ : BugReporter(d, GRBugReporterKind), Eng(eng) {}
~GRBugReporter() override;
- /// getEngine - Return the analysis engine used to analyze a given
- /// function or method.
- ExprEngine &getEngine() { return Eng; }
-
/// getGraph - Get the exploded graph created by the analysis engine
/// for the analyzed method or function.
ExplodedGraph &getGraph();
@@ -521,16 +527,14 @@ public:
/// engine.
ProgramStateManager &getStateManager();
- /// Generates a path corresponding to one of the given bug reports.
- ///
- /// Which report is used for path generation is not specified. The
- /// bug reporter will try to pick the shortest path, but this is not
- /// guaranteed.
+ /// \p bugReports A set of bug reports within a *single* equivalence class
///
- /// \return True if the report was valid and a path was generated,
- /// false if the reports should be considered invalid.
- bool generatePathDiagnostic(PathDiagnostic &PD, PathDiagnosticConsumer &PC,
- ArrayRef<BugReport*> &bugReports) override;
+ /// \return A mapping from consumers to the corresponding diagnostics.
+ /// Iterates through the bug reports within a single equivalence class,
+ /// stops at a first non-invalidated report.
+ std::unique_ptr<DiagnosticForConsumerMapTy>
+ generatePathDiagnostics(ArrayRef<PathDiagnosticConsumer *> consumers,
+ ArrayRef<BugReport *> &bugReports) override;
/// classof - Used by isa<>, cast<>, and dyn_cast<>.
static bool classof(const BugReporter* R) {
@@ -538,13 +542,29 @@ public:
}
};
+
+class NodeMapClosure : public BugReport::NodeResolver {
+ InterExplodedGraphMap &M;
+
+public:
+ NodeMapClosure(InterExplodedGraphMap &m) : M(m) {}
+
+ const ExplodedNode *getOriginalNode(const ExplodedNode *N) override {
+ return M.lookup(N);
+ }
+};
+
class BugReporterContext {
- virtual void anchor();
GRBugReporter &BR;
+ NodeMapClosure NMC;
+
+ virtual void anchor();
+
public:
- BugReporterContext(GRBugReporter& br) : BR(br) {}
+ BugReporterContext(GRBugReporter &br, InterExplodedGraphMap &Backmap)
+ : BR(br), NMC(Backmap) {}
- virtual ~BugReporterContext() {}
+ virtual ~BugReporterContext() = default;
GRBugReporter& getBugReporter() { return BR; }
@@ -554,7 +574,7 @@ public:
return BR.getStateManager();
}
- SValBuilder& getSValBuilder() {
+ SValBuilder &getSValBuilder() {
return getStateManager().getSValBuilder();
}
@@ -566,11 +586,15 @@ public:
return BR.getSourceManager();
}
- virtual BugReport::NodeResolver& getNodeResolver() = 0;
+ AnalyzerOptions &getAnalyzerOptions() {
+ return BR.getAnalyzerOptions();
+ }
+
+ NodeMapClosure& getNodeResolver() { return NMC; }
};
-} // end GR namespace
+} // namespace ento
-} // end clang namespace
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
index 2043896fd26fe..92118b0fbee25 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
@@ -1,4 +1,4 @@
-//===--- BugReporterVisitors.h - Generate PathDiagnostics -------*- C++ -*-===//
+//===- BugReporterVisitors.h - Generate PathDiagnostics ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,11 +15,21 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H
#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
namespace clang {
+
+class BinaryOperator;
class CFGBlock;
+class DeclRefExpr;
+class Expr;
+class Stmt;
namespace ento {
@@ -29,13 +39,7 @@ class ExplodedNode;
class MemRegion;
class PathDiagnosticPiece;
-/// \brief BugReporterVisitors are used to add custom diagnostics along a path.
-///
-/// Custom visitors should subclass the BugReporterVisitorImpl class for a
-/// default implementation of the clone() method.
-/// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
-/// default implementation of clone() will NOT do the right thing, and you
-/// will have to provide your own implementation.)
+/// BugReporterVisitors are used to add custom diagnostics along a path.
class BugReporterVisitor : public llvm::FoldingSetNode {
public:
BugReporterVisitor() = default;
@@ -43,19 +47,13 @@ public:
BugReporterVisitor(BugReporterVisitor &&) {}
virtual ~BugReporterVisitor();
- /// \brief Returns a copy of this BugReporter.
- ///
- /// Custom BugReporterVisitors should not override this method directly.
- /// Instead, they should inherit from BugReporterVisitorImpl and provide
- /// a protected or public copy constructor.
- ///
- /// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
- /// default implementation of clone() will NOT do the right thing, and you
- /// will have to provide your own implementation.)
- virtual std::unique_ptr<BugReporterVisitor> clone() const = 0;
-
- /// \brief Return a diagnostic piece which should be associated with the
+ /// Return a diagnostic piece which should be associated with the
/// given node.
+ /// Note that this function does *not* get run on the very last node
+ /// of the report, as the PathDiagnosticPiece associated with the
+ /// last node should be unique.
+ /// Use {@code getEndPath} to customize the note associated with the report
+ /// end instead.
///
/// The last parameter can be used to register a new visitor with the given
/// BugReport while processing a node.
@@ -63,43 +61,32 @@ public:
VisitNode(const ExplodedNode *Succ, const ExplodedNode *Pred,
BugReporterContext &BRC, BugReport &BR) = 0;
- /// \brief Provide custom definition for the final diagnostic piece on the
+ /// Last function called on the visitor, no further calls to VisitNode
+ /// would follow.
+ virtual void finalizeVisitor(BugReporterContext &BRC,
+ const ExplodedNode *EndPathNode,
+ BugReport &BR);
+
+ /// Provide custom definition for the final diagnostic piece on the
/// path - the piece, which is displayed before the path is expanded.
///
- /// If returns NULL the default implementation will be used.
- /// Also note that at most one visitor of a BugReport should generate a
- /// non-NULL end of path diagnostic piece.
- virtual std::unique_ptr<PathDiagnosticPiece>
+ /// NOTE that this function can be implemented on at most one used visitor,
+ /// and otherwise it crahes at runtime.
+ virtual std::shared_ptr<PathDiagnosticPiece>
getEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR);
virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
- /// \brief Generates the default final diagnostic piece.
- static std::unique_ptr<PathDiagnosticPiece>
+ /// Generates the default final diagnostic piece.
+ static std::shared_ptr<PathDiagnosticPiece>
getDefaultEndPath(BugReporterContext &BRC, const ExplodedNode *N,
BugReport &BR);
};
-/// This class provides a convenience implementation for clone() using the
-/// Curiously-Recurring Template Pattern. If you are implementing a custom
-/// BugReporterVisitor, subclass BugReporterVisitorImpl and provide a public
-/// or protected copy constructor.
-///
-/// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
-/// default implementation of clone() will NOT do the right thing, and you
-/// will have to provide your own implementation.)
-template <class DERIVED>
-class BugReporterVisitorImpl : public BugReporterVisitor {
- std::unique_ptr<BugReporterVisitor> clone() const override {
- return llvm::make_unique<DERIVED>(*static_cast<const DERIVED *>(this));
- }
-};
-
-class FindLastStoreBRVisitor final
- : public BugReporterVisitorImpl<FindLastStoreBRVisitor> {
+class FindLastStoreBRVisitor final : public BugReporterVisitor {
const MemRegion *R;
SVal V;
- bool Satisfied;
+ bool Satisfied = false;
/// If the visitor is tracking the value directly responsible for the
/// bug, we are going to employ false positive suppression.
@@ -113,10 +100,7 @@ public:
FindLastStoreBRVisitor(KnownSVal V, const MemRegion *R,
bool InEnableNullFPSuppression)
- : R(R),
- V(V),
- Satisfied(false),
- EnableNullFPSuppression(InEnableNullFPSuppression) {}
+ : R(R), V(V), EnableNullFPSuppression(InEnableNullFPSuppression) {}
void Profile(llvm::FoldingSetNodeID &ID) const override;
@@ -126,22 +110,20 @@ public:
BugReport &BR) override;
};
-class TrackConstraintBRVisitor final
- : public BugReporterVisitorImpl<TrackConstraintBRVisitor> {
+class TrackConstraintBRVisitor final : public BugReporterVisitor {
DefinedSVal Constraint;
bool Assumption;
- bool IsSatisfied;
+ bool IsSatisfied = false;
bool IsZeroCheck;
/// We should start tracking from the last node along the path in which the
/// value is constrained.
- bool IsTrackingTurnedOn;
+ bool IsTrackingTurnedOn = false;
public:
TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
- : Constraint(constraint), Assumption(assumption), IsSatisfied(false),
- IsZeroCheck(!Assumption && Constraint.getAs<Loc>()),
- IsTrackingTurnedOn(false) {}
+ : Constraint(constraint), Assumption(assumption),
+ IsZeroCheck(!Assumption && Constraint.getAs<Loc>()) {}
void Profile(llvm::FoldingSetNodeID &ID) const override;
@@ -157,15 +139,12 @@ public:
private:
/// Checks if the constraint is valid in the current state.
bool isUnderconstrained(const ExplodedNode *N) const;
-
};
/// \class NilReceiverBRVisitor
-/// \brief Prints path notes when a message is sent to a nil receiver.
-class NilReceiverBRVisitor final
- : public BugReporterVisitorImpl<NilReceiverBRVisitor> {
+/// Prints path notes when a message is sent to a nil receiver.
+class NilReceiverBRVisitor final : public BugReporterVisitor {
public:
-
void Profile(llvm::FoldingSetNodeID &ID) const override {
static int x = 0;
ID.AddPointer(&x);
@@ -182,9 +161,7 @@ public:
};
/// Visitor that tries to report interesting diagnostics from conditions.
-class ConditionBRVisitor final
- : public BugReporterVisitorImpl<ConditionBRVisitor> {
-
+class ConditionBRVisitor final : public BugReporterVisitor {
// FIXME: constexpr initialization isn't supported by MSVC2013.
static const char *const GenericTrueMessage;
static const char *const GenericFalseMessage;
@@ -243,11 +220,11 @@ public:
static bool isPieceMessageGeneric(const PathDiagnosticPiece *Piece);
};
-/// \brief Suppress reports that might lead to known false positives.
+/// Suppress reports that might lead to known false positives.
///
/// Currently this suppresses reports based on locations of bugs.
class LikelyFalsePositiveSuppressionBRVisitor final
- : public BugReporterVisitorImpl<LikelyFalsePositiveSuppressionBRVisitor> {
+ : public BugReporterVisitor {
public:
static void *getTag() {
static int Tag = 0;
@@ -265,19 +242,16 @@ public:
return nullptr;
}
- std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
- const ExplodedNode *N,
- BugReport &BR) override;
+ void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *N,
+ BugReport &BR) override;
};
-/// \brief When a region containing undefined value or '0' value is passed
+/// When a region containing undefined value or '0' value is passed
/// as an argument in a call, marks the call as interesting.
///
/// As a result, BugReporter will not prune the path through the function even
/// if the region's contents are not modified/accessed by the call.
-class UndefOrNullArgVisitor final
- : public BugReporterVisitorImpl<UndefOrNullArgVisitor> {
-
+class UndefOrNullArgVisitor final : public BugReporterVisitor {
/// The interesting memory region this visitor is tracking.
const MemRegion *R;
@@ -296,21 +270,20 @@ public:
BugReport &BR) override;
};
-class SuppressInlineDefensiveChecksVisitor final
- : public BugReporterVisitorImpl<SuppressInlineDefensiveChecksVisitor> {
+class SuppressInlineDefensiveChecksVisitor final : public BugReporterVisitor {
/// The symbolic value for which we are tracking constraints.
/// This value is constrained to null in the end of path.
DefinedSVal V;
/// Track if we found the node where the constraint was first added.
- bool IsSatisfied;
+ bool IsSatisfied = false;
/// Since the visitors can be registered on nodes previous to the last
/// node in the BugReport, but the path traversal always starts with the last
/// node, the visitor invariant (that we start with a node in which V is null)
/// might not hold when node visitation starts. We are going to start tracking
/// from the last node in which the value is null.
- bool IsTrackingTurnedOn;
+ bool IsTrackingTurnedOn = false;
public:
SuppressInlineDefensiveChecksVisitor(DefinedSVal Val, const ExplodedNode *N);
@@ -327,13 +300,11 @@ public:
BugReport &BR) override;
};
-class CXXSelfAssignmentBRVisitor final
- : public BugReporterVisitorImpl<CXXSelfAssignmentBRVisitor> {
-
- bool Satisfied;
+class CXXSelfAssignmentBRVisitor final : public BugReporterVisitor {
+ bool Satisfied = false;
public:
- CXXSelfAssignmentBRVisitor() : Satisfied(false) {}
+ CXXSelfAssignmentBRVisitor() = default;
void Profile(llvm::FoldingSetNodeID &ID) const override {}
@@ -343,6 +314,44 @@ public:
BugReport &BR) override;
};
+/// The bug visitor prints a diagnostic message at the location where a given
+/// variable was tainted.
+class TaintBugVisitor final : public BugReporterVisitor {
+private:
+ const SVal V;
+
+public:
+ TaintBugVisitor(const SVal V) : V(V) {}
+ void Profile(llvm::FoldingSetNodeID &ID) const override { ID.Add(V); }
+
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
+};
+
+/// The bug visitor will walk all the nodes in a path and collect all the
+/// constraints. When it reaches the root node, will create a refutation
+/// manager and check if the constraints are satisfiable
+class FalsePositiveRefutationBRVisitor final : public BugReporterVisitor {
+private:
+ /// Holds the constraints in a given path
+ ConstraintRangeTy Constraints;
+
+public:
+ FalsePositiveRefutationBRVisitor();
+
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
+
+ void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *EndPathNode,
+ BugReport &BR) override;
+};
+
namespace bugreporter {
/// Attempts to add visitors to trace a null or undefined value back to its
@@ -370,10 +379,10 @@ const Stmt *GetDenomExpr(const ExplodedNode *N);
const Stmt *GetRetValExpr(const ExplodedNode *N);
bool isDeclRefExprToReference(const Expr *E);
+} // namespace bugreporter
-} // end namespace clang
-} // end namespace ento
-} // end namespace bugreporter
+} // namespace ento
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
index 18fa85c9657f6..c723f31aec266 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -1,4 +1,4 @@
-//===--- BugType.h - Bug Information Desciption ----------------*- C++ -*-===//
+//===--- BugType.h - Bug Information Description ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,27 +32,39 @@ private:
const CheckName Check;
const std::string Name;
const std::string Category;
- bool SuppressonSink;
+ const CheckerBase *Checker;
+ bool SuppressOnSink;
virtual void anchor();
+
public:
- BugType(class CheckName check, StringRef name, StringRef cat)
- : Check(check), Name(name), Category(cat), SuppressonSink(false) {}
- BugType(const CheckerBase *checker, StringRef name, StringRef cat)
- : Check(checker->getCheckName()), Name(name), Category(cat),
- SuppressonSink(false) {}
- virtual ~BugType() {}
-
- // FIXME: Should these be made strings as well?
+ BugType(CheckName Check, StringRef Name, StringRef Cat)
+ : Check(Check), Name(Name), Category(Cat), Checker(nullptr),
+ SuppressOnSink(false) {}
+ BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat)
+ : Check(Checker->getCheckName()), Name(Name), Category(Cat),
+ Checker(Checker), SuppressOnSink(false) {}
+ virtual ~BugType() = default;
+
StringRef getName() const { return Name; }
StringRef getCategory() const { return Category; }
- StringRef getCheckName() const { return Check.getName(); }
+ StringRef getCheckName() const {
+ // FIXME: This is a workaround to ensure that the correct check name is used
+ // The check names are set after the constructors are run.
+ // In case the BugType object is initialized in the checker's ctor
+ // the Check field will be empty. To circumvent this problem we use
+ // CheckerBase whenever it is possible.
+ StringRef CheckName =
+ Checker ? Checker->getCheckName().getName() : Check.getName();
+ assert(!CheckName.empty() && "Check name is not set properly.");
+ return CheckName;
+ }
/// isSuppressOnSink - Returns true if bug reports associated with this bug
/// type should be suppressed if the end node of the report is post-dominated
/// by a sink node.
- bool isSuppressOnSink() const { return SuppressonSink; }
- void setSuppressOnSink(bool x) { SuppressonSink = x; }
+ bool isSuppressOnSink() const { return SuppressOnSink; }
+ void setSuppressOnSink(bool x) { SuppressOnSink = x; }
virtual void FlushReports(BugReporter& BR);
};
@@ -74,7 +86,7 @@ public:
StringRef getDescription() const { return desc; }
};
-} // end GR namespace
+} // end ento namespace
} // end clang namespace
#endif
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index f31ab2cd81cd2..b18d3c9b3031c 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -1,4 +1,4 @@
-//===--- PathDiagnostic.h - Path-Specific Diagnostic Handling ---*- C++ -*-===//
+//===- PathDiagnostic.h - Path-Specific Diagnostic Handling -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,37 +14,49 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
-#include "clang/Analysis/ProgramPoint.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include <cassert>
#include <deque>
#include <iterator>
#include <list>
+#include <map>
+#include <memory>
+#include <set>
#include <string>
+#include <utility>
#include <vector>
namespace clang {
-class ConditionalOperator;
+
class AnalysisDeclContext;
class BinaryOperator;
-class CompoundStmt;
+class CallEnter;
+class CallExitEnd;
+class CallExpr;
+class ConditionalOperator;
class Decl;
+class Expr;
class LocationContext;
class MemberExpr;
-class ParentMap;
class ProgramPoint;
class SourceManager;
-class Stmt;
-class CallExpr;
namespace ento {
class ExplodedNode;
class SymExpr;
-typedef const SymExpr* SymbolRef;
+
+using SymbolRef = const SymExpr *;
//===----------------------------------------------------------------------===//
// High-level interface for handlers of path-sensitive diagnostics.
@@ -58,15 +70,15 @@ public:
public:
PDFileEntry(llvm::FoldingSetNodeID &NodeID) : NodeID(NodeID) {}
- typedef std::vector<std::pair<StringRef, StringRef> > ConsumerFiles;
+ using ConsumerFiles = std::vector<std::pair<StringRef, StringRef>>;
- /// \brief A vector of <consumer,file> pairs.
+ /// A vector of <consumer,file> pairs.
ConsumerFiles files;
- /// \brief A precomputed hash tag used for uniquing PDFileEntry objects.
+ /// A precomputed hash tag used for uniquing PDFileEntry objects.
const llvm::FoldingSetNodeID NodeID;
- /// \brief Used for profiling in the FoldingSet.
+ /// Used for profiling in the FoldingSet.
void Profile(llvm::FoldingSetNodeID &ID) { ID = NodeID; }
};
@@ -88,8 +100,9 @@ public:
private:
virtual void anchor();
+
public:
- PathDiagnosticConsumer() : flushed(false) {}
+ PathDiagnosticConsumer() = default;
virtual ~PathDiagnosticConsumer();
void FlushDiagnostics(FilesMade *FilesMade);
@@ -101,7 +114,17 @@ public:
void HandlePathDiagnostic(std::unique_ptr<PathDiagnostic> D);
- enum PathGenerationScheme { None, Minimal, Extensive, AlternateExtensive };
+ enum PathGenerationScheme {
+ /// Only runs visitors, no output generated.
+ None,
+
+ /// Used for HTML and text output.
+ Minimal,
+
+ /// Used for plist output, used for "arrows" generation.
+ Extensive,
+ };
+
virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
virtual bool supportsLogicalOpControlFlow() const { return false; }
@@ -110,7 +133,7 @@ public:
virtual bool supportsCrossFileDiagnostics() const { return false; }
protected:
- bool flushed;
+ bool flushed = false;
llvm::FoldingSet<PathDiagnostic> Diags;
};
@@ -120,31 +143,28 @@ protected:
class PathDiagnosticRange : public SourceRange {
public:
- bool isPoint;
+ bool isPoint = false;
PathDiagnosticRange(SourceRange R, bool isP = false)
- : SourceRange(R), isPoint(isP) {}
-
- PathDiagnosticRange() : isPoint(false) {}
+ : SourceRange(R), isPoint(isP) {}
+ PathDiagnosticRange() = default;
};
-typedef llvm::PointerUnion<const LocationContext*, AnalysisDeclContext*>
- LocationOrAnalysisDeclContext;
+using LocationOrAnalysisDeclContext =
+ llvm::PointerUnion<const LocationContext *, AnalysisDeclContext *>;
class PathDiagnosticLocation {
private:
- enum Kind { RangeK, SingleLocK, StmtK, DeclK } K;
- const Stmt *S;
- const Decl *D;
- const SourceManager *SM;
+ enum Kind { RangeK, SingleLocK, StmtK, DeclK } K = SingleLocK;
+
+ const Stmt *S = nullptr;
+ const Decl *D = nullptr;
+ const SourceManager *SM = nullptr;
FullSourceLoc Loc;
PathDiagnosticRange Range;
- PathDiagnosticLocation(SourceLocation L, const SourceManager &sm,
- Kind kind)
- : K(kind), S(nullptr), D(nullptr), SM(&sm),
- Loc(genLocation(L)), Range(genRange()) {
- }
+ PathDiagnosticLocation(SourceLocation L, const SourceManager &sm, Kind kind)
+ : K(kind), SM(&sm), Loc(genLocation(L)), Range(genRange()) {}
FullSourceLoc genLocation(
SourceLocation L = SourceLocation(),
@@ -155,18 +175,15 @@ private:
public:
/// Create an invalid location.
- PathDiagnosticLocation()
- : K(SingleLocK), S(nullptr), D(nullptr), SM(nullptr) {}
+ PathDiagnosticLocation() = default;
/// Create a location corresponding to the given statement.
PathDiagnosticLocation(const Stmt *s,
const SourceManager &sm,
LocationOrAnalysisDeclContext lac)
- : K(s->getLocStart().isValid() ? StmtK : SingleLocK),
- S(K == StmtK ? s : nullptr),
- D(nullptr), SM(&sm),
- Loc(genLocation(SourceLocation(), lac)),
- Range(genRange(lac)) {
+ : K(s->getLocStart().isValid() ? StmtK : SingleLocK),
+ S(K == StmtK ? s : nullptr), SM(&sm),
+ Loc(genLocation(SourceLocation(), lac)), Range(genRange(lac)) {
assert(K == SingleLocK || S);
assert(K == SingleLocK || Loc.isValid());
assert(K == SingleLocK || Range.isValid());
@@ -174,8 +191,7 @@ public:
/// Create a location corresponding to the given declaration.
PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
- : K(DeclK), S(nullptr), D(d), SM(&sm),
- Loc(genLocation()), Range(genRange()) {
+ : K(DeclK), D(d), SM(&sm), Loc(genLocation()), Range(genRange()) {
assert(D);
assert(Loc.isValid());
assert(Range.isValid());
@@ -185,8 +201,7 @@ public:
///
/// This should only be used if there are no more appropriate constructors.
PathDiagnosticLocation(SourceLocation loc, const SourceManager &sm)
- : K(SingleLocK), S(nullptr), D(nullptr), SM(&sm), Loc(loc, sm),
- Range(genRange()) {
+ : SM(&sm), Loc(loc, sm), Range(genRange()) {
assert(Loc.isValid());
assert(Range.isValid());
}
@@ -201,6 +216,15 @@ public:
static PathDiagnosticLocation createBegin(const Decl *D,
const SourceManager &SM);
+ /// Create a location for the beginning of the declaration.
+ /// The third argument is ignored, useful for generic treatment
+ /// of statements and declarations.
+ static PathDiagnosticLocation
+ createBegin(const Decl *D, const SourceManager &SM,
+ const LocationOrAnalysisDeclContext LAC) {
+ return createBegin(D, SM);
+ }
+
/// Create a location for the beginning of the statement.
static PathDiagnosticLocation createBegin(const Stmt *S,
const SourceManager &SM,
@@ -248,7 +272,7 @@ public:
const SourceManager &SM);
/// Create a location corresponding to the given valid ExplodedNode.
- static PathDiagnosticLocation create(const ProgramPoint& P,
+ static PathDiagnosticLocation create(const ProgramPoint &P,
const SourceManager &SMng);
/// Create a location corresponding to the next valid ExplodedNode as end
@@ -281,6 +305,12 @@ public:
}
const Stmt *asStmt() const { assert(isValid()); return S; }
+ const Stmt *getStmtOrNull() const {
+ if (!isValid())
+ return nullptr;
+ return asStmt();
+ }
+
const Decl *asDecl() const { assert(isValid()); return D; }
bool hasRange() const { return K == StmtK || K == RangeK || K == DeclK; }
@@ -297,21 +327,22 @@ public:
void dump() const;
- /// \brief Given an exploded node, retrieve the statement that should be used
+ /// Given an exploded node, retrieve the statement that should be used
/// for the diagnostic location.
static const Stmt *getStmt(const ExplodedNode *N);
- /// \brief Retrieve the statement corresponding to the successor node.
+ /// Retrieve the statement corresponding to the successor node.
static const Stmt *getNextStmt(const ExplodedNode *N);
};
class PathDiagnosticLocationPair {
private:
PathDiagnosticLocation Start, End;
+
public:
PathDiagnosticLocationPair(const PathDiagnosticLocation &start,
const PathDiagnosticLocation &end)
- : Start(start), End(end) {}
+ : Start(start), End(end) {}
const PathDiagnosticLocation &getStart() const { return Start; }
const PathDiagnosticLocation &getEnd() const { return End; }
@@ -344,9 +375,9 @@ private:
const Kind kind;
const DisplayHint Hint;
- /// \brief In the containing bug report, this piece is the last piece from
+ /// In the containing bug report, this piece is the last piece from
/// the main source file.
- bool LastInMainSourceFile;
+ bool LastInMainSourceFile = false;
/// A constant string that can be used to tag the PathDiagnosticPiece,
/// typically with the identification of the creator. The actual pointer
@@ -356,16 +387,14 @@ private:
std::vector<SourceRange> ranges;
- PathDiagnosticPiece() = delete;
- PathDiagnosticPiece(const PathDiagnosticPiece &P) = delete;
- void operator=(const PathDiagnosticPiece &P) = delete;
-
protected:
PathDiagnosticPiece(StringRef s, Kind k, DisplayHint hint = Below);
-
PathDiagnosticPiece(Kind k, DisplayHint hint = Below);
public:
+ PathDiagnosticPiece() = delete;
+ PathDiagnosticPiece(const PathDiagnosticPiece &) = delete;
+ PathDiagnosticPiece &operator=(const PathDiagnosticPiece &) = delete;
virtual ~PathDiagnosticPiece();
StringRef getString() const { return str; }
@@ -420,8 +449,8 @@ public:
class PathPieces : public std::list<std::shared_ptr<PathDiagnosticPiece>> {
void flattenTo(PathPieces &Primary, PathPieces &Current,
bool ShouldFlattenMacros) const;
-public:
+public:
PathPieces flatten(bool ShouldFlattenMacros) const {
PathPieces Result;
flattenTo(Result, Result, ShouldFlattenMacros);
@@ -434,12 +463,13 @@ public:
class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
private:
PathDiagnosticLocation Pos;
+
public:
PathDiagnosticSpotPiece(const PathDiagnosticLocation &pos,
StringRef s,
PathDiagnosticPiece::Kind k,
bool addPosRange = true)
- : PathDiagnosticPiece(s, k), Pos(pos) {
+ : PathDiagnosticPiece(s, k), Pos(pos) {
assert(Pos.isValid() && Pos.asLocation().isValid() &&
"PathDiagnosticSpotPiece's must have a valid location.");
if (addPosRange && Pos.hasRange()) addRange(Pos.asRange());
@@ -456,7 +486,7 @@ public:
}
};
-/// \brief Interface for classes constructing Stack hints.
+/// Interface for classes constructing Stack hints.
///
/// If a PathDiagnosticEvent occurs in a different frame than the final
/// diagnostic the hints can be used to summarize the effect of the call.
@@ -464,11 +494,11 @@ class StackHintGenerator {
public:
virtual ~StackHintGenerator() = 0;
- /// \brief Construct the Diagnostic message for the given ExplodedNode.
+ /// Construct the Diagnostic message for the given ExplodedNode.
virtual std::string getMessage(const ExplodedNode *N) = 0;
};
-/// \brief Constructs a Stack hint for the given symbol.
+/// Constructs a Stack hint for the given symbol.
///
/// The class knows how to construct the stack hint message based on
/// traversing the CallExpr associated with the call and checking if the given
@@ -481,18 +511,20 @@ private:
public:
StackHintGeneratorForSymbol(SymbolRef S, StringRef M) : Sym(S), Msg(M) {}
- ~StackHintGeneratorForSymbol() override {}
+ ~StackHintGeneratorForSymbol() override = default;
- /// \brief Search the call expression for the symbol Sym and dispatch the
+ /// Search the call expression for the symbol Sym and dispatch the
/// 'getMessageForX()' methods to construct a specific message.
std::string getMessage(const ExplodedNode *N) override;
/// Produces the message of the following form:
/// 'Msg via Nth parameter'
virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex);
+
virtual std::string getMessageForReturn(const CallExpr *CallExpr) {
return Msg;
}
+
virtual std::string getMessageForSymbolNotFound() {
return Msg;
}
@@ -511,9 +543,8 @@ public:
PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
StringRef s, bool addPosRange = true,
StackHintGenerator *stackHint = nullptr)
- : PathDiagnosticSpotPiece(pos, s, Event, addPosRange),
- CallStackHint(stackHint) {}
-
+ : PathDiagnosticSpotPiece(pos, s, Event, addPosRange),
+ CallStackHint(stackHint) {}
~PathDiagnosticEventPiece() override;
/// Mark the diagnostic piece as being potentially prunable. This
@@ -537,30 +568,19 @@ public:
std::string getCallStackMessage(const ExplodedNode *N) {
if (CallStackHint)
return CallStackHint->getMessage(N);
- return "";
+ return {};
}
void dump() const override;
- static inline bool classof(const PathDiagnosticPiece *P) {
+ static bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == Event;
}
};
class PathDiagnosticCallPiece : public PathDiagnosticPiece {
- PathDiagnosticCallPiece(const Decl *callerD,
- const PathDiagnosticLocation &callReturnPos)
- : PathDiagnosticPiece(Call), Caller(callerD), Callee(nullptr),
- NoExit(false), IsCalleeAnAutosynthesizedPropertyAccessor(false),
- callReturn(callReturnPos) {}
-
- PathDiagnosticCallPiece(PathPieces &oldPath, const Decl *caller)
- : PathDiagnosticPiece(Call), Caller(caller), Callee(nullptr),
- NoExit(true), IsCalleeAnAutosynthesizedPropertyAccessor(false),
- path(oldPath) {}
-
const Decl *Caller;
- const Decl *Callee;
+ const Decl *Callee = nullptr;
// Flag signifying that this diagnostic has only call enter and no matching
// call exit.
@@ -568,12 +588,20 @@ class PathDiagnosticCallPiece : public PathDiagnosticPiece {
// Flag signifying that the callee function is an Objective-C autosynthesized
// property getter or setter.
- bool IsCalleeAnAutosynthesizedPropertyAccessor;
+ bool IsCalleeAnAutosynthesizedPropertyAccessor = false;
// The custom string, which should appear after the call Return Diagnostic.
// TODO: Should we allow multiple diagnostics?
std::string CallStackMessage;
+ PathDiagnosticCallPiece(const Decl *callerD,
+ const PathDiagnosticLocation &callReturnPos)
+ : PathDiagnosticPiece(Call), Caller(callerD), NoExit(false),
+ callReturn(callReturnPos) {}
+ PathDiagnosticCallPiece(PathPieces &oldPath, const Decl *caller)
+ : PathDiagnosticPiece(Call), Caller(caller), NoExit(true),
+ path(oldPath) {}
+
public:
PathDiagnosticLocation callEnter;
PathDiagnosticLocation callEnterWithin;
@@ -588,13 +616,9 @@ public:
void setCallee(const CallEnter &CE, const SourceManager &SM);
bool hasCallStackMessage() { return !CallStackMessage.empty(); }
- void setCallStackMessage(StringRef st) {
- CallStackMessage = st;
- }
+ void setCallStackMessage(StringRef st) { CallStackMessage = st; }
- PathDiagnosticLocation getLocation() const override {
- return callEnter;
- }
+ PathDiagnosticLocation getLocation() const override { return callEnter; }
std::shared_ptr<PathDiagnosticEventPiece> getCallEnterEvent() const;
std::shared_ptr<PathDiagnosticEventPiece>
@@ -604,8 +628,8 @@ public:
void flattenLocations() override {
callEnter.flatten();
callReturn.flatten();
- for (PathPieces::iterator I = path.begin(),
- E = path.end(); I != E; ++I) (*I)->flattenLocations();
+ for (const auto &I : path)
+ I->flattenLocations();
}
static std::shared_ptr<PathDiagnosticCallPiece>
@@ -619,28 +643,29 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const override;
- static inline bool classof(const PathDiagnosticPiece *P) {
+ static bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == Call;
}
};
class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece {
std::vector<PathDiagnosticLocationPair> LPairs;
+
public:
PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos,
const PathDiagnosticLocation &endPos,
StringRef s)
- : PathDiagnosticPiece(s, ControlFlow) {
- LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
- }
+ : PathDiagnosticPiece(s, ControlFlow) {
+ LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
+ }
PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos,
const PathDiagnosticLocation &endPos)
- : PathDiagnosticPiece(ControlFlow) {
- LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
- }
+ : PathDiagnosticPiece(ControlFlow) {
+ LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
+ }
- ~PathDiagnosticControlFlowPiece() override;
+ ~PathDiagnosticControlFlowPiece() override;
PathDiagnosticLocation getStartLocation() const {
assert(!LPairs.empty() &&
@@ -668,20 +693,23 @@ public:
return getStartLocation();
}
- typedef std::vector<PathDiagnosticLocationPair>::iterator iterator;
+ using iterator = std::vector<PathDiagnosticLocationPair>::iterator;
+
iterator begin() { return LPairs.begin(); }
- iterator end() { return LPairs.end(); }
+ iterator end() { return LPairs.end(); }
void flattenLocations() override {
- for (iterator I=begin(), E=end(); I!=E; ++I) I->flatten();
+ for (auto &I : *this)
+ I.flatten();
}
- typedef std::vector<PathDiagnosticLocationPair>::const_iterator
- const_iterator;
+ using const_iterator =
+ std::vector<PathDiagnosticLocationPair>::const_iterator;
+
const_iterator begin() const { return LPairs.begin(); }
- const_iterator end() const { return LPairs.end(); }
+ const_iterator end() const { return LPairs.end(); }
- static inline bool classof(const PathDiagnosticPiece *P) {
+ static bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == ControlFlow;
}
@@ -693,8 +721,7 @@ public:
class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece {
public:
PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos)
- : PathDiagnosticSpotPiece(pos, "", Macro) {}
-
+ : PathDiagnosticSpotPiece(pos, "", Macro) {}
~PathDiagnosticMacroPiece() override;
PathPieces subPieces;
@@ -703,11 +730,11 @@ public:
void flattenLocations() override {
PathDiagnosticSpotPiece::flattenLocations();
- for (PathPieces::iterator I = subPieces.begin(),
- E = subPieces.end(); I != E; ++I) (*I)->flattenLocations();
+ for (const auto &I : subPieces)
+ I->flattenLocations();
}
- static inline bool classof(const PathDiagnosticPiece *P) {
+ static bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == Macro;
}
@@ -721,10 +748,9 @@ public:
PathDiagnosticNotePiece(const PathDiagnosticLocation &Pos, StringRef S,
bool AddPosRange = true)
: PathDiagnosticSpotPiece(Pos, S, Note, AddPosRange) {}
-
~PathDiagnosticNotePiece() override;
- static inline bool classof(const PathDiagnosticPiece *P) {
+ static bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == Note;
}
@@ -733,6 +759,9 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const override;
};
+/// File IDs mapped to sets of line numbers.
+using FilesToLineNumsMap = std::map<unsigned, std::set<unsigned>>;
+
/// PathDiagnostic - PathDiagnostic objects represent a single path-sensitive
/// diagnostic. It represents an ordered-collection of PathDiagnosticPieces,
/// each which represent the pieces of the path.
@@ -745,24 +774,27 @@ class PathDiagnostic : public llvm::FoldingSetNode {
std::string Category;
std::deque<std::string> OtherDesc;
- /// \brief Loc The location of the path diagnostic report.
+ /// Loc The location of the path diagnostic report.
PathDiagnosticLocation Loc;
PathPieces pathImpl;
SmallVector<PathPieces *, 3> pathStack;
- /// \brief Important bug uniqueing location.
+ /// Important bug uniqueing location.
/// The location info is useful to differentiate between bugs.
PathDiagnosticLocation UniqueingLoc;
const Decl *UniqueingDecl;
- PathDiagnostic() = delete;
+ /// Lines executed in the path.
+ std::unique_ptr<FilesToLineNumsMap> ExecutedLines;
+
public:
+ PathDiagnostic() = delete;
PathDiagnostic(StringRef CheckName, const Decl *DeclWithIssue,
StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
StringRef category, PathDiagnosticLocation LocationToUnique,
- const Decl *DeclToUnique);
-
+ const Decl *DeclToUnique,
+ std::unique_ptr<FilesToLineNumsMap> ExecutedLines);
~PathDiagnostic();
const PathPieces &path;
@@ -788,7 +820,7 @@ public:
bool isWithinCall() const { return !pathStack.empty(); }
- void setEndOfPath(std::unique_ptr<PathDiagnosticPiece> EndPiece) {
+ void setEndOfPath(std::shared_ptr<PathDiagnosticPiece> EndPiece) {
assert(!Loc.isValid() && "End location already set!");
Loc = EndPiece->getLocation();
assert(Loc.isValid() && "Invalid location for end-of-path piece");
@@ -801,21 +833,17 @@ public:
VerboseDesc += S;
}
- void resetPath() {
- pathStack.clear();
- pathImpl.clear();
- Loc = PathDiagnosticLocation();
- }
-
- /// \brief If the last piece of the report point to the header file, resets
+ /// If the last piece of the report point to the header file, resets
/// the location of the report to be the last location in the main source
/// file.
void resetDiagnosticLocationToMainFile();
StringRef getVerboseDescription() const { return VerboseDesc; }
+
StringRef getShortDescription() const {
return ShortDesc.empty() ? VerboseDesc : ShortDesc;
}
+
StringRef getCheckName() const { return CheckName; }
StringRef getBugType() const { return BugType; }
StringRef getCategory() const { return Category; }
@@ -825,30 +853,38 @@ public:
/// where the bug manifests.
const Decl *getDeclWithIssue() const { return DeclWithIssue; }
- typedef std::deque<std::string>::const_iterator meta_iterator;
+ using meta_iterator = std::deque<std::string>::const_iterator;
+
meta_iterator meta_begin() const { return OtherDesc.begin(); }
meta_iterator meta_end() const { return OtherDesc.end(); }
void addMeta(StringRef s) { OtherDesc.push_back(s); }
+ using filesmap_iterator = FilesToLineNumsMap::const_iterator;
+
+ filesmap_iterator executedLines_begin() const {
+ return ExecutedLines->begin();
+ }
+
+ filesmap_iterator executedLines_end() const { return ExecutedLines->end(); }
+
PathDiagnosticLocation getLocation() const {
- assert(Loc.isValid() && "No report location set yet!");
return Loc;
}
- /// \brief Get the location on which the report should be uniqued.
+ /// Get the location on which the report should be uniqued.
PathDiagnosticLocation getUniqueingLoc() const {
return UniqueingLoc;
}
- /// \brief Get the declaration containing the uniqueing location.
+ /// Get the declaration containing the uniqueing location.
const Decl *getUniqueingDecl() const {
return UniqueingDecl;
}
void flattenLocations() {
Loc.flatten();
- for (PathPieces::iterator I = pathImpl.begin(), E = pathImpl.end();
- I != E; ++I) (*I)->flattenLocations();
+ for (const auto &I : pathImpl)
+ I->flattenLocations();
}
/// Profiles the diagnostic, independent of the path it references.
@@ -864,8 +900,8 @@ public:
void FullProfile(llvm::FoldingSetNodeID &ID) const;
};
-} // end GR namespace
+} // namespace ento
-} //end clang namespace
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index f9477762c7585..45b7a61139ea7 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -254,9 +254,9 @@ public:
class EndFunction {
template <typename CHECKER>
- static void _checkEndFunction(void *checker,
+ static void _checkEndFunction(void *checker, const ReturnStmt *RS,
CheckerContext &C) {
- ((const CHECKER *)checker)->checkEndFunction(C);
+ ((const CHECKER *)checker)->checkEndFunction(RS, C);
}
public:
@@ -283,6 +283,22 @@ public:
}
};
+class NewAllocator {
+ template <typename CHECKER>
+ static void _checkNewAllocator(void *checker, const CXXNewExpr *NE,
+ SVal Target, CheckerContext &C) {
+ ((const CHECKER *)checker)->checkNewAllocator(NE, Target, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForNewAllocator(
+ CheckerManager::CheckNewAllocatorFunc(checker,
+ _checkNewAllocator<CHECKER>));
+ }
+};
+
class LiveSymbols {
template <typename CHECKER>
static void _checkLiveSymbols(void *checker, ProgramStateRef state,
@@ -532,7 +548,7 @@ public:
}
};
-/// \brief We dereferenced a location that may be null.
+/// We dereferenced a location that may be null.
struct ImplicitNullDerefEvent {
SVal Location;
bool IsLoad;
@@ -544,7 +560,7 @@ struct ImplicitNullDerefEvent {
bool IsDirectDereference;
};
-/// \brief A helper class which wraps a boolean value set to false by default.
+/// A helper class which wraps a boolean value set to false by default.
///
/// This class should behave exactly like 'bool' except that it doesn't need to
/// be explicitly initialized.
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 88cb08a4b647c..33a794061a384 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -1,4 +1,4 @@
-//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===//
+//===- CheckerManager.h - Static Analyzer Checker Manager -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,51 +16,62 @@
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Basic/LangOptions.h"
-#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
-#include <utility>
+#include "llvm/ADT/StringRef.h"
#include <vector>
namespace clang {
- class Decl;
- class Stmt;
- class CallExpr;
+
+class AnalyzerOptions;
+class CallExpr;
+class CXXNewExpr;
+class Decl;
+class LocationContext;
+class Stmt;
+class TranslationUnitDecl;
namespace ento {
- class CheckerBase;
- class CheckerRegistry;
- class ExprEngine;
- class AnalysisManager;
- class BugReporter;
- class CheckerContext;
- class ObjCMethodCall;
- class SVal;
- class ExplodedNode;
- class ExplodedNodeSet;
- class ExplodedGraph;
- class ProgramState;
- class NodeBuilder;
- struct NodeBuilderContext;
- class MemRegion;
- class SymbolReaper;
+
+class AnalysisManager;
+class BugReporter;
+class CallEvent;
+class CheckerBase;
+class CheckerContext;
+class CheckerRegistry;
+class ExplodedGraph;
+class ExplodedNode;
+class ExplodedNodeSet;
+class ExprEngine;
+class MemRegion;
+struct NodeBuilderContext;
+class ObjCMethodCall;
+class RegionAndSymbolInvalidationTraits;
+class SVal;
+class SymbolReaper;
template <typename T> class CheckerFn;
template <typename RET, typename... Ps>
class CheckerFn<RET(Ps...)> {
- typedef RET (*Func)(void *, Ps...);
+ using Func = RET (*)(void *, Ps...);
+
Func Fn;
+
public:
CheckerBase *Checker;
- CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
+
+ CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) {}
+
RET operator()(Ps... ps) const {
return Fn(Checker, ps...);
}
};
-/// \brief Describes the different reasons a pointer escapes
+/// Describes the different reasons a pointer escapes
/// during analysis.
enum PointerEscapeKind {
/// A pointer escapes due to binding its value to a location
@@ -85,12 +96,15 @@ enum PointerEscapeKind {
// name strings have a lifetime that keeps them alive at least until the path
// diagnostics have been processed.
class CheckName {
- StringRef Name;
friend class ::clang::ento::CheckerRegistry;
+
+ StringRef Name;
+
explicit CheckName(StringRef Name) : Name(Name) {}
public:
CheckName() = default;
+
StringRef getName() const { return Name; }
};
@@ -121,40 +135,27 @@ public:
const LangOptions &getLangOpts() const { return LangOpts; }
AnalyzerOptions &getAnalyzerOptions() { return AOptions; }
- typedef CheckerBase *CheckerRef;
- typedef const void *CheckerTag;
- typedef CheckerFn<void ()> CheckerDtor;
+ using CheckerRef = CheckerBase *;
+ using CheckerTag = const void *;
+ using CheckerDtor = CheckerFn<void ()>;
//===----------------------------------------------------------------------===//
// registerChecker
//===----------------------------------------------------------------------===//
- /// \brief Used to register checkers.
+ /// Used to register checkers.
+ /// All arguments are automatically passed through to the checker
+ /// constructor.
///
/// \returns a pointer to the checker object.
- template <typename CHECKER>
- CHECKER *registerChecker() {
+ template <typename CHECKER, typename... AT>
+ CHECKER *registerChecker(AT... Args) {
CheckerTag tag = getTag<CHECKER>();
CheckerRef &ref = CheckerTags[tag];
if (ref)
return static_cast<CHECKER *>(ref); // already registered.
- CHECKER *checker = new CHECKER();
- checker->Name = CurrentCheckName;
- CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
- CHECKER::_register(checker, *this);
- ref = checker;
- return checker;
- }
-
- template <typename CHECKER>
- CHECKER *registerChecker(AnalyzerOptions &AOpts) {
- CheckerTag tag = getTag<CHECKER>();
- CheckerRef &ref = CheckerTags[tag];
- if (ref)
- return static_cast<CHECKER *>(ref); // already registered.
-
- CHECKER *checker = new CHECKER(AOpts);
+ CHECKER *checker = new CHECKER(Args...);
checker->Name = CurrentCheckName;
CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
CHECKER::_register(checker, *this);
@@ -166,11 +167,11 @@ public:
// Functions for running checkers for AST traversing..
//===----------------------------------------------------------------------===//
- /// \brief Run checkers handling Decls.
+ /// Run checkers handling Decls.
void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
BugReporter &BR);
- /// \brief Run checkers handling Decls containing a Stmt body.
+ /// Run checkers handling Decls containing a Stmt body.
void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
BugReporter &BR);
@@ -178,7 +179,7 @@ public:
// Functions for running checkers for path-sensitive checking.
//===----------------------------------------------------------------------===//
- /// \brief Run checkers for pre-visiting Stmts.
+ /// Run checkers for pre-visiting Stmts.
///
/// The notification is performed for every explored CFGElement, which does
/// not include the control flow statements such as IfStmt.
@@ -191,7 +192,7 @@ public:
runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
}
- /// \brief Run checkers for post-visiting Stmts.
+ /// Run checkers for post-visiting Stmts.
///
/// The notification is performed for every explored CFGElement, which does
/// not include the control flow statements such as IfStmt.
@@ -205,13 +206,13 @@ public:
runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
}
- /// \brief Run checkers for visiting Stmts.
+ /// Run checkers for visiting Stmts.
void runCheckersForStmt(bool isPreVisit,
ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
const Stmt *S, ExprEngine &Eng,
bool wasInlined = false);
- /// \brief Run checkers for pre-visiting obj-c messages.
+ /// Run checkers for pre-visiting obj-c messages.
void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
const ObjCMethodCall &msg,
@@ -219,7 +220,7 @@ public:
runCheckersForObjCMessage(ObjCMessageVisitKind::Pre, Dst, Src, msg, Eng);
}
- /// \brief Run checkers for post-visiting obj-c messages.
+ /// Run checkers for post-visiting obj-c messages.
void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
const ObjCMethodCall &msg,
@@ -229,7 +230,7 @@ public:
wasInlined);
}
- /// \brief Run checkers for visiting an obj-c message to nil.
+ /// Run checkers for visiting an obj-c message to nil.
void runCheckersForObjCMessageNil(ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
const ObjCMethodCall &msg,
@@ -238,21 +239,20 @@ public:
Eng);
}
-
- /// \brief Run checkers for visiting obj-c messages.
+ /// Run checkers for visiting obj-c messages.
void runCheckersForObjCMessage(ObjCMessageVisitKind visitKind,
ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
const ObjCMethodCall &msg, ExprEngine &Eng,
bool wasInlined = false);
- /// \brief Run checkers for pre-visiting obj-c messages.
+ /// Run checkers for pre-visiting obj-c messages.
void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
const CallEvent &Call, ExprEngine &Eng) {
runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
}
- /// \brief Run checkers for post-visiting obj-c messages.
+ /// Run checkers for post-visiting obj-c messages.
void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
const CallEvent &Call, ExprEngine &Eng,
bool wasInlined = false) {
@@ -260,13 +260,13 @@ public:
wasInlined);
}
- /// \brief Run checkers for visiting obj-c messages.
+ /// Run checkers for visiting obj-c messages.
void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
const CallEvent &Call, ExprEngine &Eng,
bool wasInlined = false);
- /// \brief Run checkers for load/store of a location.
+ /// Run checkers for load/store of a location.
void runCheckersForLocation(ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
SVal location,
@@ -275,35 +275,43 @@ public:
const Stmt *BoundEx,
ExprEngine &Eng);
- /// \brief Run checkers for binding of a value to a location.
+ /// Run checkers for binding of a value to a location.
void runCheckersForBind(ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
SVal location, SVal val,
const Stmt *S, ExprEngine &Eng,
const ProgramPoint &PP);
- /// \brief Run checkers for end of analysis.
+ /// Run checkers for end of analysis.
void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
ExprEngine &Eng);
- /// \brief Run checkers on beginning of function.
+ /// Run checkers on beginning of function.
void runCheckersForBeginFunction(ExplodedNodeSet &Dst,
const BlockEdge &L,
ExplodedNode *Pred,
ExprEngine &Eng);
- /// \brief Run checkers on end of function.
+ /// Run checkers on end of function.
void runCheckersForEndFunction(NodeBuilderContext &BC,
ExplodedNodeSet &Dst,
ExplodedNode *Pred,
- ExprEngine &Eng);
+ ExprEngine &Eng,
+ const ReturnStmt *RS);
- /// \brief Run checkers for branch condition.
+ /// Run checkers for branch condition.
void runCheckersForBranchCondition(const Stmt *condition,
ExplodedNodeSet &Dst, ExplodedNode *Pred,
ExprEngine &Eng);
- /// \brief Run checkers for live symbols.
+ /// Run checkers between C++ operator new and constructor calls.
+ void runCheckersForNewAllocator(const CXXNewExpr *NE, SVal Target,
+ ExplodedNodeSet &Dst,
+ ExplodedNode *Pred,
+ ExprEngine &Eng,
+ bool wasInlined = false);
+
+ /// Run checkers for live symbols.
///
/// Allows modifying SymbolReaper object. For example, checkers can explicitly
/// register symbols of interest as live. These symbols will not be marked
@@ -311,7 +319,7 @@ public:
void runCheckersForLiveSymbols(ProgramStateRef state,
SymbolReaper &SymReaper);
- /// \brief Run checkers for dead symbols.
+ /// Run checkers for dead symbols.
///
/// Notifies checkers when symbols become dead. For example, this allows
/// checkers to aggressively clean up/reduce the checker state and produce
@@ -322,7 +330,7 @@ public:
ExprEngine &Eng,
ProgramPoint::Kind K);
- /// \brief Run checkers for region changes.
+ /// Run checkers for region changes.
///
/// This corresponds to the check::RegionChanges callback.
/// \param state The current program state.
@@ -341,7 +349,7 @@ public:
const LocationContext *LCtx,
const CallEvent *Call);
- /// \brief Run checkers when pointers escape.
+ /// Run checkers when pointers escape.
///
/// This notifies the checkers about pointer escape, which occurs whenever
/// the analyzer cannot track the symbol any more. For example, as a
@@ -361,25 +369,25 @@ public:
const InvalidatedSymbols &Escaped,
const CallEvent *Call,
PointerEscapeKind Kind,
- RegionAndSymbolInvalidationTraits *ITraits);
+ RegionAndSymbolInvalidationTraits *ITraits);
- /// \brief Run checkers for handling assumptions on symbolic values.
+ /// Run checkers for handling assumptions on symbolic values.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
SVal Cond, bool Assumption);
- /// \brief Run checkers for evaluating a call.
+ /// Run checkers for evaluating a call.
///
/// Warning: Currently, the CallEvent MUST come from a CallExpr!
void runCheckersForEvalCall(ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
const CallEvent &CE, ExprEngine &Eng);
- /// \brief Run checkers for the entire Translation Unit.
+ /// Run checkers for the entire Translation Unit.
void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
AnalysisManager &mgr,
BugReporter &BR);
- /// \brief Run checkers for debug-printing a ProgramState.
+ /// Run checkers for debug-printing a ProgramState.
///
/// Unlike most other callbacks, any checker can simply implement the virtual
/// method CheckerBase::printState if it has custom data to print.
@@ -397,10 +405,11 @@ public:
// Functions used by the registration mechanism, checkers should not touch
// these directly.
- typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
- CheckDeclFunc;
+ using CheckDeclFunc =
+ CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>;
+
+ using HandlesDeclFunc = bool (*)(const Decl *D);
- typedef bool (*HandlesDeclFunc)(const Decl *D);
void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
void _registerForBody(CheckDeclFunc checkfn);
@@ -409,67 +418,67 @@ public:
// Internal registration functions for path-sensitive checking.
//===----------------------------------------------------------------------===//
- typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
+ using CheckStmtFunc = CheckerFn<void (const Stmt *, CheckerContext &)>;
- typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
- CheckObjCMessageFunc;
+ using CheckObjCMessageFunc =
+ CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>;
- typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
- CheckCallFunc;
+ using CheckCallFunc =
+ CheckerFn<void (const CallEvent &, CheckerContext &)>;
- typedef CheckerFn<void (const SVal &location, bool isLoad,
- const Stmt *S,
- CheckerContext &)>
- CheckLocationFunc;
+ using CheckLocationFunc =
+ CheckerFn<void (const SVal &location, bool isLoad, const Stmt *S,
+ CheckerContext &)>;
- typedef CheckerFn<void (const SVal &location, const SVal &val,
- const Stmt *S, CheckerContext &)>
- CheckBindFunc;
+ using CheckBindFunc =
+ CheckerFn<void (const SVal &location, const SVal &val, const Stmt *S,
+ CheckerContext &)>;
- typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
- CheckEndAnalysisFunc;
+ using CheckEndAnalysisFunc =
+ CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>;
- typedef CheckerFn<void (CheckerContext &)>
- CheckBeginFunctionFunc;
+ using CheckBeginFunctionFunc = CheckerFn<void (CheckerContext &)>;
- typedef CheckerFn<void (CheckerContext &)>
- CheckEndFunctionFunc;
+ using CheckEndFunctionFunc =
+ CheckerFn<void (const ReturnStmt *, CheckerContext &)>;
- typedef CheckerFn<void (const Stmt *, CheckerContext &)>
- CheckBranchConditionFunc;
+ using CheckBranchConditionFunc =
+ CheckerFn<void (const Stmt *, CheckerContext &)>;
+
+ using CheckNewAllocatorFunc =
+ CheckerFn<void (const CXXNewExpr *, SVal, CheckerContext &)>;
- typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
- CheckDeadSymbolsFunc;
+ using CheckDeadSymbolsFunc =
+ CheckerFn<void (SymbolReaper &, CheckerContext &)>;
- typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
+ using CheckLiveSymbolsFunc = CheckerFn<void (ProgramStateRef,SymbolReaper &)>;
- typedef CheckerFn<ProgramStateRef (ProgramStateRef,
- const InvalidatedSymbols *symbols,
- ArrayRef<const MemRegion *> ExplicitRegions,
- ArrayRef<const MemRegion *> Regions,
- const LocationContext *LCtx,
- const CallEvent *Call)>
- CheckRegionChangesFunc;
+ using CheckRegionChangesFunc =
+ CheckerFn<ProgramStateRef (ProgramStateRef,
+ const InvalidatedSymbols *symbols,
+ ArrayRef<const MemRegion *> ExplicitRegions,
+ ArrayRef<const MemRegion *> Regions,
+ const LocationContext *LCtx,
+ const CallEvent *Call)>;
- typedef CheckerFn<ProgramStateRef (ProgramStateRef,
- const InvalidatedSymbols &Escaped,
- const CallEvent *Call,
- PointerEscapeKind Kind,
- RegionAndSymbolInvalidationTraits *ITraits)>
- CheckPointerEscapeFunc;
+ using CheckPointerEscapeFunc =
+ CheckerFn<ProgramStateRef (ProgramStateRef,
+ const InvalidatedSymbols &Escaped,
+ const CallEvent *Call, PointerEscapeKind Kind,
+ RegionAndSymbolInvalidationTraits *ITraits)>;
- typedef CheckerFn<ProgramStateRef (ProgramStateRef,
- const SVal &cond, bool assumption)>
- EvalAssumeFunc;
+ using EvalAssumeFunc =
+ CheckerFn<ProgramStateRef (ProgramStateRef, const SVal &cond,
+ bool assumption)>;
- typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
- EvalCallFunc;
+ using EvalCallFunc = CheckerFn<bool (const CallExpr *, CheckerContext &)>;
- typedef CheckerFn<void (const TranslationUnitDecl *,
- AnalysisManager&, BugReporter &)>
- CheckEndOfTranslationUnit;
+ using CheckEndOfTranslationUnit =
+ CheckerFn<void (const TranslationUnitDecl *, AnalysisManager &,
+ BugReporter &)>;
+
+ using HandlesStmtFunc = bool (*)(const Stmt *D);
- typedef bool (*HandlesStmtFunc)(const Stmt *D);
void _registerForPreStmt(CheckStmtFunc checkfn,
HandlesStmtFunc isForStmtFn);
void _registerForPostStmt(CheckStmtFunc checkfn,
@@ -489,11 +498,13 @@ public:
void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
- void _registerForBeginFunction(CheckEndFunctionFunc checkfn);
+ void _registerForBeginFunction(CheckBeginFunctionFunc checkfn);
void _registerForEndFunction(CheckEndFunctionFunc checkfn);
void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
+ void _registerForNewAllocator(CheckNewAllocatorFunc checkfn);
+
void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
@@ -514,8 +525,8 @@ public:
// Internal registration functions for events.
//===----------------------------------------------------------------------===//
- typedef void *EventTag;
- typedef CheckerFn<void (const void *event)> CheckEventFunc;
+ using EventTag = void *;
+ using CheckEventFunc = CheckerFn<void (const void *event)>;
template <typename EVENT>
void _registerListenerForEvent(CheckEventFunc checkfn) {
@@ -535,8 +546,8 @@ public:
if (I == Events.end())
return;
const EventInfo &info = I->second;
- for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
- info.Checkers[i](&event);
+ for (const auto Checker : info.Checkers)
+ Checker(&event);
}
//===----------------------------------------------------------------------===//
@@ -562,8 +573,8 @@ private:
std::vector<CheckDeclFunc> BodyCheckers;
- typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
- typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
+ using CachedDeclCheckers = SmallVector<CheckDeclFunc, 4>;
+ using CachedDeclCheckersMapTy = llvm::DenseMap<unsigned, CachedDeclCheckers>;
CachedDeclCheckersMapTy CachedDeclCheckersMap;
struct StmtCheckerInfo {
@@ -573,8 +584,8 @@ private:
};
std::vector<StmtCheckerInfo> StmtCheckers;
- typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
- typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy;
+ using CachedStmtCheckers = SmallVector<CheckStmtFunc, 4>;
+ using CachedStmtCheckersMapTy = llvm::DenseMap<unsigned, CachedStmtCheckers>;
CachedStmtCheckersMapTy CachedStmtCheckersMap;
const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
@@ -603,6 +614,8 @@ private:
std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
+ std::vector<CheckNewAllocatorFunc> NewAllocatorCheckers;
+
std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
@@ -619,16 +632,17 @@ private:
struct EventInfo {
SmallVector<CheckEventFunc, 4> Checkers;
- bool HasDispatcher;
- EventInfo() : HasDispatcher(false) { }
+ bool HasDispatcher = false;
+
+ EventInfo() = default;
};
- typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
+ using EventsTy = llvm::DenseMap<EventTag, EventInfo>;
EventsTy Events;
};
-} // end ento namespace
+} // namespace ento
-} // end clang namespace
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
index 3b26ed3e1a09a..912a601b61c49 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
@@ -1,4 +1,4 @@
-//===--- CheckerRegistry.h - Maintains all available checkers ---*- C++ -*-===//
+//===- CheckerRegistry.h - Maintains all available checkers -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,6 +12,9 @@
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <cstddef>
#include <vector>
// FIXME: move this information to an HTML file in docs/.
@@ -64,8 +67,9 @@
#endif
namespace clang {
-class DiagnosticsEngine;
+
class AnalyzerOptions;
+class DiagnosticsEngine;
namespace ento {
@@ -81,17 +85,18 @@ class CheckerRegistry {
public:
/// Initialization functions perform any necessary setup for a checker.
/// They should include a call to CheckerManager::registerChecker.
- typedef void (*InitializationFunction)(CheckerManager &);
+ using InitializationFunction = void (*)(CheckerManager &);
+
struct CheckerInfo {
InitializationFunction Initialize;
StringRef FullName;
StringRef Desc;
CheckerInfo(InitializationFunction fn, StringRef name, StringRef desc)
- : Initialize(fn), FullName(name), Desc(desc) {}
+ : Initialize(fn), FullName(name), Desc(desc) {}
};
- typedef std::vector<CheckerInfo> CheckerInfoList;
+ using CheckerInfoList = std::vector<CheckerInfo>;
private:
template <typename T>
@@ -136,7 +141,8 @@ private:
mutable llvm::StringMap<size_t> Packages;
};
-} // end namespace ento
-} // end namespace clang
+} // namespace ento
-#endif
+} // namespace clang
+
+#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H
diff --git a/include/clang/StaticAnalyzer/Core/IssueHash.h b/include/clang/StaticAnalyzer/Core/IssueHash.h
index b3c4f1465594e..8cb6631fae747 100644
--- a/include/clang/StaticAnalyzer/Core/IssueHash.h
+++ b/include/clang/StaticAnalyzer/Core/IssueHash.h
@@ -17,7 +17,7 @@ class SourceManager;
class FullSourceLoc;
class LangOptions;
-/// \brief Get an MD5 hash to help identify bugs.
+/// Get an MD5 hash to help identify bugs.
///
/// This function returns a hash that helps identify bugs within a source file.
/// This identification can be utilized to diff diagnostic results on different
@@ -41,7 +41,7 @@ llvm::SmallString<32> GetIssueHash(const SourceManager &SM,
llvm::StringRef BugType, const Decl *D,
const LangOptions &LangOpts);
-/// \brief Get the string representation of issue hash. See GetIssueHash() for
+/// Get the string representation of issue hash. See GetIssueHash() for
/// more information.
std::string GetIssueString(const SourceManager &SM, FullSourceLoc &IssueLoc,
llvm::StringRef CheckerName, llvm::StringRef BugType,
diff --git a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
index ce512fd301ee7..2e81aa38c8de3 100644
--- a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
+++ b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
@@ -1,4 +1,4 @@
-//===--- PathDiagnosticClients.h - Path Diagnostic Clients ------*- C++ -*-===//
+//===--- PathDiagnosticConsumers.h - Path Diagnostic Clients ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
index cc8a9b8ef0719..93edfcef2d5aa 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
@@ -16,7 +16,7 @@
namespace clang {
namespace ento {
-/// \brief A record of the "type" of an APSInt, used for conversions.
+/// A record of the "type" of an APSInt, used for conversions.
class APSIntType {
uint32_t BitWidth;
bool IsUnsigned;
@@ -31,7 +31,7 @@ public:
uint32_t getBitWidth() const { return BitWidth; }
bool isUnsigned() const { return IsUnsigned; }
- /// \brief Convert a given APSInt, in place, to match this type.
+ /// Convert a given APSInt, in place, to match this type.
///
/// This behaves like a C cast: converting 255u8 (0xFF) to s16 gives
/// 255 (0x00FF), and converting -1s8 (0xFF) to u16 gives 65535 (0xFFFF).
@@ -93,7 +93,7 @@ public:
return BitWidth == Other.BitWidth && IsUnsigned == Other.IsUnsigned;
}
- /// \brief Provide an ordering for finding a common conversion type.
+ /// Provide an ordering for finding a common conversion type.
///
/// Unsigned integers are considered to be better conversion types than
/// signed integers of the same width.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index 15b930bc3f1eb..02b335761e708 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -126,6 +126,36 @@ public:
AnalysisDeclContext *getAnalysisDeclContext(const Decl *D) {
return AnaCtxMgr.getContext(D);
}
+
+ static bool isInCodeFile(SourceLocation SL, const SourceManager &SM) {
+ if (SM.isInMainFile(SL))
+ return true;
+
+ // Support the "unified sources" compilation method (eg. WebKit) that
+ // involves producing non-header files that include other non-header files.
+ // We should be included directly from a UnifiedSource* file
+ // and we shouldn't be a header - which is a very safe defensive check.
+ SourceLocation IL = SM.getIncludeLoc(SM.getFileID(SL));
+ if (!IL.isValid() || !SM.isInMainFile(IL))
+ return false;
+ // Should rather be "file name starts with", but the current .getFilename
+ // includes the full path.
+ if (SM.getFilename(IL).contains("UnifiedSource")) {
+ // It might be great to reuse FrontendOptions::getInputKindForExtension()
+ // but for now it doesn't discriminate between code and header files.
+ return llvm::StringSwitch<bool>(SM.getFilename(SL).rsplit('.').second)
+ .Cases("c", "m", "mm", "C", "cc", "cp", true)
+ .Cases("cpp", "CPP", "c++", "cxx", "cppm", true)
+ .Default(false);
+ }
+
+ return false;
+ }
+
+ bool isInCodeFile(SourceLocation SL) {
+ const SourceManager &SM = getASTContext().getSourceManager();
+ return isInCodeFile(SL, SM);
+ }
};
} // enAnaCtxMgrspace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index 4aa87443e4c22..0bbc6500d6ec3 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -1,4 +1,4 @@
-//=== BasicValueFactory.h - Basic values for Path Sens analysis --*- C++ -*---//
+//==- BasicValueFactory.h - Basic values for Path Sens analysis --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -17,12 +17,26 @@
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BASICVALUEFACTORY_H
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableList.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Allocator.h"
+#include <cassert>
+#include <cstdint>
+#include <utility>
namespace clang {
+
+class CXXBaseSpecifier;
+class DeclaratorDecl;
+
namespace ento {
class CompoundValData : public llvm::FoldingSetNode {
@@ -34,7 +48,8 @@ public:
assert(NonLoc::isCompoundType(t));
}
- typedef llvm::ImmutableList<SVal>::iterator iterator;
+ using iterator = llvm::ImmutableList<SVal>::iterator;
+
iterator begin() const { return L.begin(); }
iterator end() const { return L.end(); }
@@ -47,6 +62,7 @@ public:
class LazyCompoundValData : public llvm::FoldingSetNode {
StoreRef store;
const TypedValueRegion *region;
+
public:
LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r)
: store(st), region(r) {
@@ -63,16 +79,17 @@ public:
void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); }
};
-class PointerToMemberData: public llvm::FoldingSetNode {
+class PointerToMemberData : public llvm::FoldingSetNode {
const DeclaratorDecl *D;
llvm::ImmutableList<const CXXBaseSpecifier *> L;
public:
PointerToMemberData(const DeclaratorDecl *D,
llvm::ImmutableList<const CXXBaseSpecifier *> L)
- : D(D), L(L) {}
+ : D(D), L(L) {}
+
+ using iterator = llvm::ImmutableList<const CXXBaseSpecifier *>::iterator;
- typedef llvm::ImmutableList<const CXXBaseSpecifier *>::iterator iterator;
iterator begin() const { return L.begin(); }
iterator end() const { return L.end(); }
@@ -81,24 +98,25 @@ public:
void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, D, L); }
const DeclaratorDecl *getDeclaratorDecl() const {return D;}
+
llvm::ImmutableList<const CXXBaseSpecifier *> getCXXBaseList() const {
return L;
}
};
class BasicValueFactory {
- typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
- APSIntSetTy;
+ using APSIntSetTy =
+ llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt>>;
ASTContext &Ctx;
llvm::BumpPtrAllocator& BPAlloc;
- APSIntSetTy APSIntSet;
- void * PersistentSVals;
- void * PersistentSValPairs;
+ APSIntSetTy APSIntSet;
+ void *PersistentSVals = nullptr;
+ void *PersistentSValPairs = nullptr;
llvm::ImmutableList<SVal>::Factory SValListFactory;
- llvm::ImmutableList<const CXXBaseSpecifier*>::Factory CXXBaseListFactory;
+ llvm::ImmutableList<const CXXBaseSpecifier *>::Factory CXXBaseListFactory;
llvm::FoldingSet<CompoundValData> CompoundValDataSet;
llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet;
llvm::FoldingSet<PointerToMemberData> PointerToMemberDataSet;
@@ -109,9 +127,8 @@ class BasicValueFactory {
public:
BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator &Alloc)
- : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(nullptr),
- PersistentSValPairs(nullptr), SValListFactory(Alloc),
- CXXBaseListFactory(Alloc) {}
+ : Ctx(ctx), BPAlloc(Alloc), SValListFactory(Alloc),
+ CXXBaseListFactory(Alloc) {}
~BasicValueFactory();
@@ -147,57 +164,57 @@ public:
return getValue(TargetType.convert(From));
}
- const llvm::APSInt& getIntValue(uint64_t X, bool isUnsigned) {
+ const llvm::APSInt &getIntValue(uint64_t X, bool isUnsigned) {
QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy;
return getValue(X, T);
}
- inline const llvm::APSInt& getMaxValue(const llvm::APSInt &v) {
+ const llvm::APSInt &getMaxValue(const llvm::APSInt &v) {
return getValue(APSIntType(v).getMaxValue());
}
- inline const llvm::APSInt& getMinValue(const llvm::APSInt &v) {
+ const llvm::APSInt &getMinValue(const llvm::APSInt &v) {
return getValue(APSIntType(v).getMinValue());
}
- inline const llvm::APSInt& getMaxValue(QualType T) {
+ const llvm::APSInt &getMaxValue(QualType T) {
return getValue(getAPSIntType(T).getMaxValue());
}
- inline const llvm::APSInt& getMinValue(QualType T) {
+ const llvm::APSInt &getMinValue(QualType T) {
return getValue(getAPSIntType(T).getMinValue());
}
- inline const llvm::APSInt& Add1(const llvm::APSInt& V) {
+ const llvm::APSInt &Add1(const llvm::APSInt &V) {
llvm::APSInt X = V;
++X;
return getValue(X);
}
- inline const llvm::APSInt& Sub1(const llvm::APSInt& V) {
+ const llvm::APSInt &Sub1(const llvm::APSInt &V) {
llvm::APSInt X = V;
--X;
return getValue(X);
}
- inline const llvm::APSInt& getZeroWithTypeSize(QualType T) {
+ const llvm::APSInt &getZeroWithTypeSize(QualType T) {
assert(T->isScalarType());
return getValue(0, Ctx.getTypeSize(T), true);
}
- inline const llvm::APSInt& getZeroWithPtrWidth(bool isUnsigned = true) {
+ const llvm::APSInt &getZeroWithPtrWidth(bool isUnsigned = true) {
return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
}
- inline const llvm::APSInt &getIntWithPtrWidth(uint64_t X, bool isUnsigned) {
+ const llvm::APSInt &getIntWithPtrWidth(uint64_t X, bool isUnsigned) {
return getValue(X, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
}
- inline const llvm::APSInt& getTruthValue(bool b, QualType T) {
- return getValue(b ? 1 : 0, Ctx.getTypeSize(T), false);
+ const llvm::APSInt &getTruthValue(bool b, QualType T) {
+ return getValue(b ? 1 : 0, Ctx.getIntWidth(T), true);
}
- inline const llvm::APSInt& getTruthValue(bool b) {
+ const llvm::APSInt &getTruthValue(bool b) {
return getTruthValue(b, Ctx.getLogicalOperationType());
}
@@ -229,7 +246,7 @@ public:
return CXXBaseListFactory.add(CBS, L);
}
- const clang::ento::PointerToMemberData *accumCXXBase(
+ const PointerToMemberData *accumCXXBase(
llvm::iterator_range<CastExpr::path_const_iterator> PathRange,
const nonloc::PointerToMember &PTM);
@@ -246,8 +263,8 @@ public:
const SVal* getPersistentSVal(SVal X);
};
-} // end GR namespace
+} // namespace ento
-} // end clang namespace
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_BASICVALUEFACTORY_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
index 1d779e6cb6ec0..b94dadff23427 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
@@ -25,7 +25,7 @@ class StackFrameContext;
namespace ento {
/// \class BlockCounter
-/// \brief An abstract data type used to count the number of times a given
+/// An abstract data type used to count the number of times a given
/// block has been visited along a path analyzed by CoreEngine.
class BlockCounter {
void *Data;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index 9fec217aca725..9c667f912e9fd 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -1,4 +1,4 @@
-//===- CallEvent.h - Wrapper for all function and method calls ----*- C++ -*--//
+//===- CallEvent.h - Wrapper for all function and method calls --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,19 +16,42 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
-#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <limits>
#include <utility>
namespace clang {
+
+class LocationContext;
class ProgramPoint;
class ProgramPointTag;
+class StackFrameContext;
namespace ento {
@@ -48,31 +71,31 @@ enum CallEventKind {
};
class CallEvent;
-class CallEventManager;
/// This class represents a description of a function call using the number of
/// arguments and the name of the function.
class CallDescription {
friend CallEvent;
- mutable IdentifierInfo *II;
- mutable bool IsLookupDone;
+
+ mutable IdentifierInfo *II = nullptr;
+ mutable bool IsLookupDone = false;
StringRef FuncName;
unsigned RequiredArgs;
public:
- const static unsigned NoArgRequirement = ~0;
- /// \brief Constructs a CallDescription object.
+ const static unsigned NoArgRequirement = std::numeric_limits<unsigned>::max();
+
+ /// Constructs a CallDescription object.
///
/// @param FuncName The name of the function that will be matched.
///
/// @param RequiredArgs The number of arguments that is expected to match a
- /// call. Omit this parameter to match every occurance of call with a given
+ /// call. Omit this parameter to match every occurrence of call with a given
/// name regardless the number of arguments.
CallDescription(StringRef FuncName, unsigned RequiredArgs = NoArgRequirement)
- : II(nullptr), IsLookupDone(false), FuncName(FuncName),
- RequiredArgs(RequiredArgs) {}
+ : FuncName(FuncName), RequiredArgs(RequiredArgs) {}
- /// \brief Get the name of the function that this object matches.
+ /// Get the name of the function that this object matches.
StringRef getFunctionName() const { return FuncName; }
};
@@ -95,7 +118,7 @@ public:
};
/// \class RuntimeDefinition
-/// \brief Defines the runtime definition of the called function.
+/// Defines the runtime definition of the called function.
///
/// Encapsulates the information we have about which Decl will be used
/// when the call is executed on the given path. When dealing with dynamic
@@ -104,21 +127,22 @@ public:
class RuntimeDefinition {
/// The Declaration of the function which could be called at runtime.
/// NULL if not available.
- const Decl *D;
+ const Decl *D = nullptr;
/// The region representing an object (ObjC/C++) on which the method is
/// called. With dynamic dispatch, the method definition depends on the
/// runtime type of this object. NULL when the DynamicTypeInfo is
/// precise.
- const MemRegion *R;
+ const MemRegion *R = nullptr;
public:
- RuntimeDefinition(): D(nullptr), R(nullptr) {}
- RuntimeDefinition(const Decl *InD): D(InD), R(nullptr) {}
+ RuntimeDefinition() = default;
+ RuntimeDefinition(const Decl *InD): D(InD) {}
RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {}
+
const Decl *getDecl() { return D; }
- /// \brief Check if the definition we have is precise.
+ /// Check if the definition we have is precise.
/// If not, it is possible that the call dispatches to another definition at
/// execution time.
bool mayHaveOtherDefinitions() { return R != nullptr; }
@@ -128,7 +152,7 @@ public:
const MemRegion *getDispatchRegion() { return R; }
};
-/// \brief Represents an abstract call to a function or method along a
+/// Represents an abstract call to a function or method along a
/// particular path.
///
/// CallEvents are created through the factory methods of CallEventManager.
@@ -139,15 +163,13 @@ public:
/// Use the "Data" and "Location" fields instead.
class CallEvent {
public:
- typedef CallEventKind Kind;
+ using Kind = CallEventKind;
private:
ProgramStateRef State;
const LocationContext *LCtx;
llvm::PointerUnion<const Expr *, const Decl *> Origin;
- void operator=(const CallEvent &) = delete;
-
protected:
// This is user data for subclasses.
const void *Data;
@@ -158,9 +180,10 @@ protected:
SourceLocation Location;
private:
- mutable unsigned RefCount;
-
template <typename T> friend struct llvm::IntrusiveRefCntPtrInfo;
+
+ mutable unsigned RefCount = 0;
+
void Retain() const { ++RefCount; }
void Release() const;
@@ -168,72 +191,72 @@ protected:
friend class CallEventManager;
CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx)
- : State(std::move(state)), LCtx(lctx), Origin(E), RefCount(0) {}
+ : State(std::move(state)), LCtx(lctx), Origin(E) {}
CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx)
- : State(std::move(state)), LCtx(lctx), Origin(D), RefCount(0) {}
+ : State(std::move(state)), LCtx(lctx), Origin(D) {}
// DO NOT MAKE PUBLIC
CallEvent(const CallEvent &Original)
- : State(Original.State), LCtx(Original.LCtx), Origin(Original.Origin),
- Data(Original.Data), Location(Original.Location), RefCount(0) {}
+ : State(Original.State), LCtx(Original.LCtx), Origin(Original.Origin),
+ Data(Original.Data), Location(Original.Location) {}
/// Copies this CallEvent, with vtable intact, into a new block of memory.
virtual void cloneTo(void *Dest) const = 0;
- /// \brief Get the value of arbitrary expressions at this point in the path.
+ /// Get the value of arbitrary expressions at this point in the path.
SVal getSVal(const Stmt *S) const {
return getState()->getSVal(S, getLocationContext());
}
+ using ValueList = SmallVectorImpl<SVal>;
- typedef SmallVectorImpl<SVal> ValueList;
-
- /// \brief Used to specify non-argument regions that will be invalidated as a
+ /// Used to specify non-argument regions that will be invalidated as a
/// result of this call.
virtual void getExtraInvalidatedValues(ValueList &Values,
RegionAndSymbolInvalidationTraits *ETraits) const {}
public:
- virtual ~CallEvent() {}
+ CallEvent &operator=(const CallEvent &) = delete;
+ virtual ~CallEvent() = default;
- /// \brief Returns the kind of call this is.
+ /// Returns the kind of call this is.
virtual Kind getKind() const = 0;
- /// \brief Returns the declaration of the function or method that will be
+ /// Returns the declaration of the function or method that will be
/// called. May be null.
virtual const Decl *getDecl() const {
return Origin.dyn_cast<const Decl *>();
}
- /// \brief The state in which the call is being evaluated.
+ /// The state in which the call is being evaluated.
const ProgramStateRef &getState() const {
return State;
}
- /// \brief The context in which the call is being evaluated.
+ /// The context in which the call is being evaluated.
const LocationContext *getLocationContext() const {
return LCtx;
}
- /// \brief Returns the definition of the function or method that will be
+ /// Returns the definition of the function or method that will be
/// called.
virtual RuntimeDefinition getRuntimeDefinition() const = 0;
- /// \brief Returns the expression whose value will be the result of this call.
+ /// Returns the expression whose value will be the result of this call.
/// May be null.
const Expr *getOriginExpr() const {
return Origin.dyn_cast<const Expr *>();
}
- /// \brief Returns the number of arguments (explicit and implicit).
+ /// Returns the number of arguments (explicit and implicit).
///
/// Note that this may be greater than the number of parameters in the
/// callee's declaration, and that it may include arguments not written in
/// the source.
virtual unsigned getNumArgs() const = 0;
- /// \brief Returns true if the callee is known to be from a system header.
+ /// Returns true if the callee is known to be from a system header.
bool isInSystemHeader() const {
const Decl *D = getDecl();
if (!D)
@@ -248,57 +271,57 @@ public:
// Special case for implicitly-declared global operator new/delete.
// These should be considered system functions.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (const auto *FD = dyn_cast<FunctionDecl>(D))
return FD->isOverloadedOperator() && FD->isImplicit() && FD->isGlobal();
return false;
}
- /// \brief Returns true if the CallEvent is a call to a function that matches
+ /// Returns true if the CallEvent is a call to a function that matches
/// the CallDescription.
///
/// Note that this function is not intended to be used to match Obj-C method
/// calls.
bool isCalled(const CallDescription &CD) const;
- /// \brief Returns a source range for the entire call, suitable for
+ /// Returns a source range for the entire call, suitable for
/// outputting in diagnostics.
virtual SourceRange getSourceRange() const {
return getOriginExpr()->getSourceRange();
}
- /// \brief Returns the value of a given argument at the time of the call.
+ /// Returns the value of a given argument at the time of the call.
virtual SVal getArgSVal(unsigned Index) const;
- /// \brief Returns the expression associated with a given argument.
+ /// Returns the expression associated with a given argument.
/// May be null if this expression does not appear in the source.
virtual const Expr *getArgExpr(unsigned Index) const { return nullptr; }
- /// \brief Returns the source range for errors associated with this argument.
+ /// Returns the source range for errors associated with this argument.
///
/// May be invalid if the argument is not written in the source.
virtual SourceRange getArgSourceRange(unsigned Index) const;
- /// \brief Returns the result type, adjusted for references.
+ /// Returns the result type, adjusted for references.
QualType getResultType() const;
- /// \brief Returns the return value of the call.
+ /// Returns the return value of the call.
///
/// This should only be called if the CallEvent was created using a state in
/// which the return value has already been bound to the origin expression.
SVal getReturnValue() const;
- /// \brief Returns true if the type of any of the non-null arguments satisfies
+ /// Returns true if the type of any of the non-null arguments satisfies
/// the condition.
bool hasNonNullArgumentsWithType(bool (*Condition)(QualType)) const;
- /// \brief Returns true if any of the arguments appear to represent callbacks.
+ /// Returns true if any of the arguments appear to represent callbacks.
bool hasNonZeroCallbackArg() const;
- /// \brief Returns true if any of the arguments is void*.
+ /// Returns true if any of the arguments is void*.
bool hasVoidPointerToNonConstArg() const;
- /// \brief Returns true if any of the arguments are known to escape to long-
+ /// Returns true if any of the arguments are known to escape to long-
/// term storage, even if this method will not modify them.
// NOTE: The exact semantics of this are still being defined!
// We don't really want a list of hardcoded exceptions in the long run,
@@ -307,7 +330,7 @@ public:
return hasNonZeroCallbackArg();
}
- /// \brief Returns true if the callee is an externally-visible function in the
+ /// Returns true if the callee is an externally-visible function in the
/// top-level namespace, such as \c malloc.
///
/// You can use this call to determine that a particular function really is
@@ -325,7 +348,7 @@ public:
// precise callbacks.
bool isGlobalCFunction(StringRef SpecificName = StringRef()) const;
- /// \brief Returns the name of the callee, if its name is a simple identifier.
+ /// Returns the name of the callee, if its name is a simple identifier.
///
/// Note that this will fail for Objective-C methods, blocks, and C++
/// overloaded operators. The former is named by a Selector rather than a
@@ -333,25 +356,25 @@ public:
// FIXME: Move this down to AnyFunctionCall once checkers have more
// precise callbacks.
const IdentifierInfo *getCalleeIdentifier() const {
- const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getDecl());
+ const auto *ND = dyn_cast_or_null<NamedDecl>(getDecl());
if (!ND)
return nullptr;
return ND->getIdentifier();
}
- /// \brief Returns an appropriate ProgramPoint for this call.
+ /// Returns an appropriate ProgramPoint for this call.
ProgramPoint getProgramPoint(bool IsPreVisit = false,
const ProgramPointTag *Tag = nullptr) const;
- /// \brief Returns a new state with all argument regions invalidated.
+ /// Returns a new state with all argument regions invalidated.
///
/// This accepts an alternate state in case some processing has already
/// occurred.
ProgramStateRef invalidateRegions(unsigned BlockCount,
ProgramStateRef Orig = nullptr) const;
- typedef std::pair<Loc, SVal> FrameBindingTy;
- typedef SmallVectorImpl<FrameBindingTy> BindingsTy;
+ using FrameBindingTy = std::pair<Loc, SVal>;
+ using BindingsTy = SmallVectorImpl<FrameBindingTy>;
/// Populates the given SmallVector with the bindings in the callee's stack
/// frame at the start of this call.
@@ -367,16 +390,16 @@ public:
return cloneWithState<CallEvent>(NewState);
}
- /// \brief Returns true if this is a statement is a function or method call
+ /// Returns true if this is a statement is a function or method call
/// of some kind.
static bool isCallStmt(const Stmt *S);
- /// \brief Returns the result type of a function or method declaration.
+ /// Returns the result type of a function or method declaration.
///
/// This will return a null QualType if the result type cannot be determined.
static QualType getDeclaredResultType(const Decl *D);
- /// \brief Returns true if the given decl is known to be variadic.
+ /// Returns true if the given decl is known to be variadic.
///
/// \p D must not be null.
static bool isVariadic(const Decl *D);
@@ -393,10 +416,10 @@ public:
/// Remember that the number of formal parameters may not match the number
/// of arguments for all calls. However, the first parameter will always
/// correspond with the argument value returned by \c getArgSVal(0).
- virtual ArrayRef<ParmVarDecl*> parameters() const = 0;
+ virtual ArrayRef<ParmVarDecl *> parameters() const = 0;
- typedef llvm::mapped_iterator<ArrayRef<ParmVarDecl*>::iterator, GetTypeFn>
- param_type_iterator;
+ using param_type_iterator =
+ llvm::mapped_iterator<ArrayRef<ParmVarDecl *>::iterator, GetTypeFn>;
/// Returns an iterator over the types of the call's formal parameters.
///
@@ -416,18 +439,17 @@ public:
void dump() const;
};
-
-/// \brief Represents a call to any sort of function that might have a
+/// Represents a call to any sort of function that might have a
/// FunctionDecl.
class AnyFunctionCall : public CallEvent {
protected:
AnyFunctionCall(const Expr *E, ProgramStateRef St,
const LocationContext *LCtx)
- : CallEvent(E, St, LCtx) {}
+ : CallEvent(E, St, LCtx) {}
AnyFunctionCall(const Decl *D, ProgramStateRef St,
const LocationContext *LCtx)
- : CallEvent(D, St, LCtx) {}
- AnyFunctionCall(const AnyFunctionCall &Other) : CallEvent(Other) {}
+ : CallEvent(D, St, LCtx) {}
+ AnyFunctionCall(const AnyFunctionCall &Other) = default;
public:
// This function is overridden by subclasses, but they must return
@@ -451,7 +473,7 @@ public:
}
};
-/// \brief Represents a C function or static C++ member function call.
+/// Represents a C function or static C++ member function call.
///
/// Example: \c fun()
class SimpleFunctionCall : public AnyFunctionCall {
@@ -460,9 +482,9 @@ class SimpleFunctionCall : public AnyFunctionCall {
protected:
SimpleFunctionCall(const CallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
- : AnyFunctionCall(CE, St, LCtx) {}
- SimpleFunctionCall(const SimpleFunctionCall &Other)
- : AnyFunctionCall(Other) {}
+ : AnyFunctionCall(CE, St, LCtx) {}
+ SimpleFunctionCall(const SimpleFunctionCall &Other) = default;
+
void cloneTo(void *Dest) const override {
new (Dest) SimpleFunctionCall(*this);
}
@@ -487,7 +509,7 @@ public:
}
};
-/// \brief Represents a call to a block.
+/// Represents a call to a block.
///
/// Example: <tt>^{ /* ... */ }()</tt>
class BlockCall : public CallEvent {
@@ -496,9 +518,9 @@ class BlockCall : public CallEvent {
protected:
BlockCall(const CallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
- : CallEvent(CE, St, LCtx) {}
+ : CallEvent(CE, St, LCtx) {}
+ BlockCall(const BlockCall &Other) = default;
- BlockCall(const BlockCall &Other) : CallEvent(Other) {}
void cloneTo(void *Dest) const override { new (Dest) BlockCall(*this); }
void getExtraInvalidatedValues(ValueList &Values,
@@ -515,7 +537,7 @@ public:
return getOriginExpr()->getArg(Index);
}
- /// \brief Returns the region associated with this instance of the block.
+ /// Returns the region associated with this instance of the block.
///
/// This may be NULL if the block's origin is unknown.
const BlockDataRegion *getBlockRegion() const;
@@ -535,7 +557,7 @@ public:
return BD->isConversionFromLambda();
}
- /// \brief For a block converted from a C++ lambda, returns the block
+ /// For a block converted from a C++ lambda, returns the block
/// VarRegion for the variable holding the captured C++ lambda record.
const VarRegion *getRegionStoringCapturedLambda() const {
assert(isConversionFromLambda());
@@ -594,28 +616,26 @@ public:
}
};
-/// \brief Represents a non-static C++ member function call, no matter how
+/// Represents a non-static C++ member function call, no matter how
/// it is written.
class CXXInstanceCall : public AnyFunctionCall {
protected:
- void getExtraInvalidatedValues(ValueList &Values,
- RegionAndSymbolInvalidationTraits *ETraits) const override;
-
CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
- : AnyFunctionCall(CE, St, LCtx) {}
+ : AnyFunctionCall(CE, St, LCtx) {}
CXXInstanceCall(const FunctionDecl *D, ProgramStateRef St,
const LocationContext *LCtx)
- : AnyFunctionCall(D, St, LCtx) {}
-
+ : AnyFunctionCall(D, St, LCtx) {}
+ CXXInstanceCall(const CXXInstanceCall &Other) = default;
- CXXInstanceCall(const CXXInstanceCall &Other) : AnyFunctionCall(Other) {}
+ void getExtraInvalidatedValues(ValueList &Values,
+ RegionAndSymbolInvalidationTraits *ETraits) const override;
public:
- /// \brief Returns the expression representing the implicit 'this' object.
+ /// Returns the expression representing the implicit 'this' object.
virtual const Expr *getCXXThisExpr() const { return nullptr; }
- /// \brief Returns the value of the implicit 'this' object.
+ /// Returns the value of the implicit 'this' object.
virtual SVal getCXXThisVal() const;
const FunctionDecl *getDecl() const override;
@@ -631,7 +651,7 @@ public:
}
};
-/// \brief Represents a non-static C++ member function call.
+/// Represents a non-static C++ member function call.
///
/// Example: \c obj.fun()
class CXXMemberCall : public CXXInstanceCall {
@@ -640,9 +660,9 @@ class CXXMemberCall : public CXXInstanceCall {
protected:
CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
- : CXXInstanceCall(CE, St, LCtx) {}
+ : CXXInstanceCall(CE, St, LCtx) {}
+ CXXMemberCall(const CXXMemberCall &Other) = default;
- CXXMemberCall(const CXXMemberCall &Other) : CXXInstanceCall(Other) {}
void cloneTo(void *Dest) const override { new (Dest) CXXMemberCall(*this); }
public:
@@ -671,7 +691,7 @@ public:
}
};
-/// \brief Represents a C++ overloaded operator call where the operator is
+/// Represents a C++ overloaded operator call where the operator is
/// implemented as a non-static member function.
///
/// Example: <tt>iter + 1</tt>
@@ -681,10 +701,9 @@ class CXXMemberOperatorCall : public CXXInstanceCall {
protected:
CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx)
- : CXXInstanceCall(CE, St, LCtx) {}
+ : CXXInstanceCall(CE, St, LCtx) {}
+ CXXMemberOperatorCall(const CXXMemberOperatorCall &Other) = default;
- CXXMemberOperatorCall(const CXXMemberOperatorCall &Other)
- : CXXInstanceCall(Other) {}
void cloneTo(void *Dest) const override {
new (Dest) CXXMemberOperatorCall(*this);
}
@@ -697,6 +716,7 @@ public:
unsigned getNumArgs() const override {
return getOriginExpr()->getNumArgs() - 1;
}
+
const Expr *getArgExpr(unsigned Index) const override {
return getOriginExpr()->getArg(Index + 1);
}
@@ -710,7 +730,7 @@ public:
}
};
-/// \brief Represents an implicit call to a C++ destructor.
+/// Represents an implicit call to a C++ destructor.
///
/// This can occur at the end of a scope (for automatic objects), at the end
/// of a full-expression (for temporaries), or as part of a delete.
@@ -718,7 +738,7 @@ class CXXDestructorCall : public CXXInstanceCall {
friend class CallEventManager;
protected:
- typedef llvm::PointerIntPair<const MemRegion *, 1, bool> DtorDataTy;
+ using DtorDataTy = llvm::PointerIntPair<const MemRegion *, 1, bool>;
/// Creates an implicit destructor.
///
@@ -730,12 +750,13 @@ protected:
CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
const MemRegion *Target, bool IsBaseDestructor,
ProgramStateRef St, const LocationContext *LCtx)
- : CXXInstanceCall(DD, St, LCtx) {
+ : CXXInstanceCall(DD, St, LCtx) {
Data = DtorDataTy(Target, IsBaseDestructor).getOpaqueValue();
Location = Trigger->getLocEnd();
}
- CXXDestructorCall(const CXXDestructorCall &Other) : CXXInstanceCall(Other) {}
+ CXXDestructorCall(const CXXDestructorCall &Other) = default;
+
void cloneTo(void *Dest) const override {new (Dest) CXXDestructorCall(*this);}
public:
@@ -744,7 +765,7 @@ public:
RuntimeDefinition getRuntimeDefinition() const override;
- /// \brief Returns the value of the implicit 'this' object.
+ /// Returns the value of the implicit 'this' object.
SVal getCXXThisVal() const override;
/// Returns true if this is a call to a base class destructor.
@@ -759,7 +780,7 @@ public:
}
};
-/// \brief Represents a call to a C++ constructor.
+/// Represents a call to a C++ constructor.
///
/// Example: \c T(1)
class CXXConstructorCall : public AnyFunctionCall {
@@ -775,11 +796,12 @@ protected:
/// \param LCtx The location context at this point in the program.
CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *Target,
ProgramStateRef St, const LocationContext *LCtx)
- : AnyFunctionCall(CE, St, LCtx) {
+ : AnyFunctionCall(CE, St, LCtx) {
Data = Target;
}
- CXXConstructorCall(const CXXConstructorCall &Other) : AnyFunctionCall(Other){}
+ CXXConstructorCall(const CXXConstructorCall &Other) = default;
+
void cloneTo(void *Dest) const override { new (Dest) CXXConstructorCall(*this); }
void getExtraInvalidatedValues(ValueList &Values,
@@ -800,7 +822,7 @@ public:
return getOriginExpr()->getArg(Index);
}
- /// \brief Returns the value of the implicit 'this' object.
+ /// Returns the value of the implicit 'this' object.
SVal getCXXThisVal() const;
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
@@ -813,7 +835,7 @@ public:
}
};
-/// \brief Represents the memory allocation call in a C++ new-expression.
+/// Represents the memory allocation call in a C++ new-expression.
///
/// This is a call to "operator new".
class CXXAllocatorCall : public AnyFunctionCall {
@@ -822,9 +844,9 @@ class CXXAllocatorCall : public AnyFunctionCall {
protected:
CXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef St,
const LocationContext *LCtx)
- : AnyFunctionCall(E, St, LCtx) {}
+ : AnyFunctionCall(E, St, LCtx) {}
+ CXXAllocatorCall(const CXXAllocatorCall &Other) = default;
- CXXAllocatorCall(const CXXAllocatorCall &Other) : AnyFunctionCall(Other) {}
void cloneTo(void *Dest) const override { new (Dest) CXXAllocatorCall(*this); }
public:
@@ -854,7 +876,7 @@ public:
}
};
-/// \brief Represents the ways an Objective-C message send can occur.
+/// Represents the ways an Objective-C message send can occur.
//
// Note to maintainers: OCM_Message should always be last, since it does not
// need to fit in the Data field's low bits.
@@ -864,7 +886,7 @@ enum ObjCMessageKind {
OCM_Message
};
-/// \brief Represents any expression that calls an Objective-C method.
+/// Represents any expression that calls an Objective-C method.
///
/// This includes all of the kinds listed in ObjCMessageKind.
class ObjCMethodCall : public CallEvent {
@@ -875,11 +897,12 @@ class ObjCMethodCall : public CallEvent {
protected:
ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St,
const LocationContext *LCtx)
- : CallEvent(Msg, St, LCtx) {
+ : CallEvent(Msg, St, LCtx) {
Data = nullptr;
}
- ObjCMethodCall(const ObjCMethodCall &Other) : CallEvent(Other) {}
+ ObjCMethodCall(const ObjCMethodCall &Other) = default;
+
void cloneTo(void *Dest) const override { new (Dest) ObjCMethodCall(*this); }
void getExtraInvalidatedValues(ValueList &Values,
@@ -893,12 +916,15 @@ public:
virtual const ObjCMessageExpr *getOriginExpr() const {
return cast<ObjCMessageExpr>(CallEvent::getOriginExpr());
}
+
const ObjCMethodDecl *getDecl() const override {
return getOriginExpr()->getMethodDecl();
}
+
unsigned getNumArgs() const override {
return getOriginExpr()->getNumArgs();
}
+
const Expr *getArgExpr(unsigned Index) const override {
return getOriginExpr()->getArg(Index);
}
@@ -906,22 +932,24 @@ public:
bool isInstanceMessage() const {
return getOriginExpr()->isInstanceMessage();
}
+
ObjCMethodFamily getMethodFamily() const {
return getOriginExpr()->getMethodFamily();
}
+
Selector getSelector() const {
return getOriginExpr()->getSelector();
}
SourceRange getSourceRange() const override;
- /// \brief Returns the value of the receiver at the time of this call.
+ /// Returns the value of the receiver at the time of this call.
SVal getReceiverSVal() const;
- /// \brief Return the value of 'self' if available.
+ /// Return the value of 'self' if available.
SVal getSelfSVal() const;
- /// \brief Get the interface for the receiver.
+ /// Get the interface for the receiver.
///
/// This works whether this is an instance message or a class message.
/// However, it currently just uses the static type of the receiver.
@@ -929,7 +957,7 @@ public:
return getOriginExpr()->getReceiverInterface();
}
- /// \brief Checks if the receiver refers to 'self' or 'super'.
+ /// Checks if the receiver refers to 'self' or 'super'.
bool isReceiverSelfOrSuper() const;
/// Returns how the message was written in the source (property access,
@@ -971,8 +999,7 @@ public:
}
};
-
-/// \brief Manages the lifetime of CallEvent objects.
+/// Manages the lifetime of CallEvent objects.
///
/// CallEventManager provides a way to create arbitrary CallEvents "on the
/// stack" as if they were value objects by keeping a cache of CallEvent-sized
@@ -984,7 +1011,8 @@ class CallEventManager {
llvm::BumpPtrAllocator &Alloc;
SmallVector<void *, 8> Cache;
- typedef SimpleFunctionCall CallEventTemplateTy;
+
+ using CallEventTemplateTy = SimpleFunctionCall;
void reclaim(const void *Memory) {
Cache.push_back(const_cast<void *>(Memory));
@@ -1032,11 +1060,9 @@ class CallEventManager {
public:
CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {}
-
CallEventRef<>
getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State);
-
CallEventRef<>
getSimpleCall(const CallExpr *E, ProgramStateRef State,
const LocationContext *LCtx);
@@ -1067,7 +1093,6 @@ public:
}
};
-
template <typename T>
CallEventRef<T> CallEvent::cloneWithState(ProgramStateRef NewState) const {
assert(isa<T>(*this) && "Cloning to unrelated type");
@@ -1099,19 +1124,22 @@ inline void CallEvent::Release() const {
this->~CallEvent();
}
-} // end namespace ento
-} // end namespace clang
+} // namespace ento
+
+} // namespace clang
namespace llvm {
- // Support isa<>, cast<>, and dyn_cast<> for CallEventRef.
- template<class T> struct simplify_type< clang::ento::CallEventRef<T> > {
- typedef const T *SimpleType;
- static SimpleType
- getSimplifiedValue(clang::ento::CallEventRef<T> Val) {
- return Val.get();
- }
- };
-}
+// Support isa<>, cast<>, and dyn_cast<> for CallEventRef.
+template<class T> struct simplify_type< clang::ento::CallEventRef<T>> {
+ using SimpleType = const T *;
+
+ static SimpleType
+ getSimplifiedValue(clang::ento::CallEventRef<T> Val) {
+ return Val.get();
+ }
+};
+
+} // namespace llvm
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 78d38a3d598dc..f3a0ca7b66081 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -111,17 +111,17 @@ public:
return Eng.getStoreManager();
}
- /// \brief Returns the previous node in the exploded graph, which includes
+ /// Returns the previous node in the exploded graph, which includes
/// the state of the program before the checker ran. Note, checkers should
/// not retain the node in their state since the nodes might get invalidated.
ExplodedNode *getPredecessor() { return Pred; }
const ProgramStateRef &getState() const { return Pred->getState(); }
- /// \brief Check if the checker changed the state of the execution; ex: added
+ /// Check if the checker changed the state of the execution; ex: added
/// a new transition or a bug report.
bool isDifferent() { return Changed; }
- /// \brief Returns the number of times the current block has been visited
+ /// Returns the number of times the current block has been visited
/// along the analyzed path.
unsigned blockCount() const {
return NB.getContext().blockCount();
@@ -174,12 +174,12 @@ public:
return Pred->getLocationContext()->getAnalysisDeclContext();
}
- /// \brief Get the blockID.
+ /// Get the blockID.
unsigned getBlockID() const {
return NB.getContext().getBlock()->getBlockID();
}
- /// \brief If the given node corresponds to a PostStore program point,
+ /// If the given node corresponds to a PostStore program point,
/// retrieve the location region as it was uttered in the code.
///
/// This utility can be useful for generating extensive diagnostics, for
@@ -191,19 +191,19 @@ public:
return nullptr;
}
- /// \brief Get the value of arbitrary expressions at this point in the path.
+ /// Get the value of arbitrary expressions at this point in the path.
SVal getSVal(const Stmt *S) const {
- return getState()->getSVal(S, getLocationContext());
+ return Pred->getSVal(S);
}
- /// \brief Returns true if the value of \p E is greater than or equal to \p
+ /// Returns true if the value of \p E is greater than or equal to \p
/// Val under unsigned comparison
bool isGreaterOrEqual(const Expr *E, unsigned long long Val);
/// Returns true if the value of \p E is negative.
bool isNegative(const Expr *E);
- /// \brief Generates a new transition in the program state graph
+ /// Generates a new transition in the program state graph
/// (ExplodedGraph). Uses the default CheckerContext predecessor node.
///
/// @param State The state of the generated node. If not specified, the state
@@ -217,7 +217,7 @@ public:
return addTransitionImpl(State ? State : getState(), false, nullptr, Tag);
}
- /// \brief Generates a new transition with the given predecessor.
+ /// Generates a new transition with the given predecessor.
/// Allows checkers to generate a chain of nodes.
///
/// @param State The state of the generated node.
@@ -230,7 +230,7 @@ public:
return addTransitionImpl(State, false, Pred, Tag);
}
- /// \brief Generate a sink node. Generating a sink stops exploration of the
+ /// Generate a sink node. Generating a sink stops exploration of the
/// given path. To create a sink node for the purpose of reporting an error,
/// checkers should use generateErrorNode() instead.
ExplodedNode *generateSink(ProgramStateRef State, ExplodedNode *Pred,
@@ -238,7 +238,7 @@ public:
return addTransitionImpl(State ? State : getState(), true, Pred, Tag);
}
- /// \brief Generate a transition to a node that will be used to report
+ /// Generate a transition to a node that will be used to report
/// an error. This node will be a sink. That is, it will stop exploration of
/// the given path.
///
@@ -251,7 +251,7 @@ public:
(Tag ? Tag : Location.getTag()));
}
- /// \brief Generate a transition to a node that will be used to report
+ /// Generate a transition to a node that will be used to report
/// an error. This node will not be a sink. That is, exploration will
/// continue along this path.
///
@@ -264,23 +264,23 @@ public:
return addTransition(State, (Tag ? Tag : Location.getTag()));
}
- /// \brief Emit the diagnostics report.
+ /// Emit the diagnostics report.
void emitReport(std::unique_ptr<BugReport> R) {
Changed = true;
Eng.getBugReporter().emitReport(std::move(R));
}
- /// \brief Returns the word that should be used to refer to the declaration
+ /// Returns the word that should be used to refer to the declaration
/// in the report.
StringRef getDeclDescription(const Decl *D);
- /// \brief Get the declaration of the called function (path-sensitive).
+ /// Get the declaration of the called function (path-sensitive).
const FunctionDecl *getCalleeDecl(const CallExpr *CE) const;
- /// \brief Get the name of the called function (path-sensitive).
+ /// Get the name of the called function (path-sensitive).
StringRef getCalleeName(const FunctionDecl *FunDecl) const;
- /// \brief Get the identifier of the called function (path-sensitive).
+ /// Get the identifier of the called function (path-sensitive).
const IdentifierInfo *getCalleeIdentifier(const CallExpr *CE) const {
const FunctionDecl *FunDecl = getCalleeDecl(CE);
if (FunDecl)
@@ -289,13 +289,13 @@ public:
return nullptr;
}
- /// \brief Get the name of the called function (path-sensitive).
+ /// Get the name of the called function (path-sensitive).
StringRef getCalleeName(const CallExpr *CE) const {
const FunctionDecl *FunDecl = getCalleeDecl(CE);
return getCalleeName(FunDecl);
}
- /// \brief Returns true if the callee is an externally-visible function in the
+ /// Returns true if the callee is an externally-visible function in the
/// top-level namespace, such as \c malloc.
///
/// If a name is provided, the function must additionally match the given
@@ -308,7 +308,7 @@ public:
static bool isCLibraryFunction(const FunctionDecl *FD,
StringRef Name = StringRef());
- /// \brief Depending on wither the location corresponds to a macro, return
+ /// Depending on wither the location corresponds to a macro, return
/// either the macro name or the token spelling.
///
/// This could be useful when checkers' logic depends on whether a function
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
index 8dda6367c2e00..7f34a7a5b19dd 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
@@ -21,6 +21,8 @@ namespace clang {
class Expr;
class VarDecl;
+class QualType;
+class AttributedType;
namespace ento {
@@ -42,6 +44,25 @@ template <class T> bool containsStmt(const Stmt *S) {
std::pair<const clang::VarDecl *, const clang::Expr *>
parseAssignment(const Stmt *S);
+// Do not reorder! The getMostNullable method relies on the order.
+// Optimization: Most pointers expected to be unspecified. When a symbol has an
+// unspecified or nonnull type non of the rules would indicate any problem for
+// that symbol. For this reason only nullable and contradicted nullability are
+// stored for a symbol. When a symbol is already contradicted, it can not be
+// casted back to nullable.
+enum class Nullability : char {
+ Contradicted, // Tracked nullability is contradicted by an explicit cast. Do
+ // not report any nullability related issue for this symbol.
+ // This nullability is propagated aggressively to avoid false
+ // positive results. See the comment on getMostNullable method.
+ Nullable,
+ Unspecified,
+ Nonnull
+};
+
+/// Get nullability annotation for a given type.
+Nullability getNullabilityAnnotation(QualType Type);
+
} // end GR namespace
} // end clang namespace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
index c01600d5c969e..d4f8fbaa43df3 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -1,4 +1,4 @@
-//== ConstraintManager.h - Constraints on symbolic values.-------*- C++ -*--==//
+//===- ConstraintManager.h - Constraints on symbolic values. ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,28 +14,44 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CONSTRAINTMANAGER_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CONSTRAINTMANAGER_H
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/SaveAndRestore.h"
+#include <memory>
+#include <utility>
namespace llvm {
+
class APSInt;
-}
+
+} // namespace llvm
namespace clang {
namespace ento {
+class ProgramStateManager;
class SubEngine;
+class SymbolReaper;
class ConditionTruthVal {
Optional<bool> Val;
+
public:
/// Construct a ConditionTruthVal indicating the constraint is constrained
/// to either true or false, depending on the boolean value provided.
ConditionTruthVal(bool constraint) : Val(constraint) {}
/// Construct a ConstraintVal indicating the constraint is underconstrained.
- ConditionTruthVal() {}
+ ConditionTruthVal() = default;
+
+ /// \return Stored value, assuming that the value is known.
+ /// Crashes otherwise.
+ bool getValue() const {
+ return *Val;
+ }
/// Return true if the constraint is perfectly constrained to 'true'.
bool isConstrainedTrue() const {
@@ -61,14 +77,14 @@ public:
class ConstraintManager {
public:
- ConstraintManager() : NotifyAssumeClients(true) {}
-
+ ConstraintManager() = default;
virtual ~ConstraintManager();
+
virtual ProgramStateRef assume(ProgramStateRef state,
DefinedSVal Cond,
bool Assumption) = 0;
- typedef std::pair<ProgramStateRef, ProgramStateRef> ProgramStatePair;
+ using ProgramStatePair = std::pair<ProgramStateRef, ProgramStateRef>;
/// Returns a pair of states (StTrue, StFalse) where the given condition is
/// assumed to be true or false, respectively.
@@ -129,7 +145,7 @@ public:
return ProgramStatePair(StInRange, StOutOfRange);
}
- /// \brief If a symbol is perfectly constrained to a constant, attempt
+ /// If a symbol is perfectly constrained to a constant, attempt
/// to return the concrete value.
///
/// Note that a ConstraintManager is not obligated to return a concretized
@@ -166,7 +182,7 @@ protected:
///
/// Note that this flag allows the ConstraintManager to be re-entrant,
/// but not thread-safe.
- bool NotifyAssumeClients;
+ bool NotifyAssumeClients = true;
/// canReasonAbout - Not all ConstraintManagers can accurately reason about
/// all SVal values. This method returns true if the ConstraintManager can
@@ -187,8 +203,7 @@ CreateRangeConstraintManager(ProgramStateManager &statemgr,
std::unique_ptr<ConstraintManager>
CreateZ3ConstraintManager(ProgramStateManager &statemgr, SubEngine *subengine);
-} // end GR namespace
+} // namespace ento
+} // namespace clang
-} // end clang namespace
-
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CONSTRAINTMANAGER_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 7472a7147fca6..5755818cd9716 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -1,4 +1,4 @@
-//==- CoreEngine.h - Path-Sensitive Dataflow Engine ----------------*- C++ -*-//
+//===- CoreEngine.h - Path-Sensitive Dataflow Engine ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,21 +15,33 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
-#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
#include <memory>
+#include <utility>
+#include <vector>
namespace clang {
-class ProgramPointTag;
-
+class AnalyzerOptions;
+class CXXBindTemporaryExpr;
+class Expr;
+class LabelDecl;
+
namespace ento {
-class NodeBuilder;
+class FunctionSummariesTy;
+class SubEngine;
//===----------------------------------------------------------------------===//
/// CoreEngine - Implements the core logic of the graph-reachability
@@ -41,23 +53,23 @@ class NodeBuilder;
/// at the statement and block-level. The analyses themselves must implement
/// any transfer function logic and the sub-expression level (if any).
class CoreEngine {
- friend struct NodeBuilderContext;
- friend class NodeBuilder;
- friend class ExprEngine;
friend class CommonNodeBuilder;
+ friend class EndOfFunctionNodeBuilder;
+ friend class ExprEngine;
friend class IndirectGotoNodeBuilder;
+ friend class NodeBuilder;
+ friend struct NodeBuilderContext;
friend class SwitchNodeBuilder;
- friend class EndOfFunctionNodeBuilder;
+
public:
- typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> >
- BlocksExhausted;
+ using BlocksExhausted =
+ std::vector<std::pair<BlockEdge, const ExplodedNode *>>;
- typedef std::vector<std::pair<const CFGBlock*, const ExplodedNode*> >
- BlocksAborted;
+ using BlocksAborted =
+ std::vector<std::pair<const CFGBlock *, const ExplodedNode *>>;
private:
-
- SubEngine& SubEng;
+ SubEngine &SubEng;
/// G - The simulation graph. Each node is a (location,state) pair.
mutable ExplodedGraph G;
@@ -106,17 +118,17 @@ private:
ExplodedNode *Pred);
private:
- CoreEngine(const CoreEngine &) = delete;
- void operator=(const CoreEngine &) = delete;
-
ExplodedNode *generateCallExitBeginNode(ExplodedNode *N,
const ReturnStmt *RS);
public:
/// Construct a CoreEngine object to analyze the provided CFG.
- CoreEngine(SubEngine &subengine, FunctionSummariesTy *FS)
- : SubEng(subengine), WList(WorkList::makeDFS()),
- BCounterFactory(G.getAllocator()), FunctionSummaries(FS) {}
+ CoreEngine(SubEngine &subengine,
+ FunctionSummariesTy *FS,
+ AnalyzerOptions &Opts);
+
+ CoreEngine(const CoreEngine &) = delete;
+ CoreEngine &operator=(const CoreEngine &) = delete;
/// getGraph - Returns the exploded graph.
ExplodedGraph &getGraph() { return G; }
@@ -125,6 +137,7 @@ public:
/// steps. Returns true if there is still simulation state on the worklist.
bool ExecuteWorkList(const LocationContext *L, unsigned Steps,
ProgramStateRef InitState);
+
/// Returns true if there is still simulation state on the worklist.
bool ExecuteWorkListWithInitialState(const LocationContext *L,
unsigned Steps,
@@ -154,28 +167,31 @@ public:
BlocksExhausted::const_iterator blocks_exhausted_begin() const {
return blocksExhausted.begin();
}
+
BlocksExhausted::const_iterator blocks_exhausted_end() const {
return blocksExhausted.end();
}
+
BlocksAborted::const_iterator blocks_aborted_begin() const {
return blocksAborted.begin();
}
+
BlocksAborted::const_iterator blocks_aborted_end() const {
return blocksAborted.end();
}
- /// \brief Enqueue the given set of nodes onto the work list.
+ /// Enqueue the given set of nodes onto the work list.
void enqueue(ExplodedNodeSet &Set);
- /// \brief Enqueue nodes that were created as a result of processing
+ /// Enqueue nodes that were created as a result of processing
/// a statement onto the work list.
void enqueue(ExplodedNodeSet &Set, const CFGBlock *Block, unsigned Idx);
- /// \brief enqueue the nodes corresponding to the end of function onto the
+ /// enqueue the nodes corresponding to the end of function onto the
/// end of path / work list.
void enqueueEndOfFunction(ExplodedNodeSet &Set, const ReturnStmt *RS);
- /// \brief Enqueue a single node created as a result of statement processing.
+ /// Enqueue a single node created as a result of statement processing.
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx);
};
@@ -184,23 +200,24 @@ struct NodeBuilderContext {
const CoreEngine &Eng;
const CFGBlock *Block;
const LocationContext *LC;
+
NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
- : Eng(E), Block(B), LC(N->getLocationContext()) { assert(B); }
+ : Eng(E), Block(B), LC(N->getLocationContext()) { assert(B); }
- /// \brief Return the CFGBlock associated with this builder.
+ /// Return the CFGBlock associated with this builder.
const CFGBlock *getBlock() const { return Block; }
- /// \brief Returns the number of times the current basic block has been
+ /// Returns the number of times the current basic block has been
/// visited on the exploded graph path.
unsigned blockCount() const {
return Eng.WList->getBlockCounter().getNumVisited(
- LC->getCurrentStackFrame(),
+ LC->getStackFrame(),
Block->getBlockID());
}
};
/// \class NodeBuilder
-/// \brief This is the simplest builder which generates nodes in the
+/// This is the simplest builder which generates nodes in the
/// ExplodedGraph.
///
/// The main benefit of the builder is that it automatically tracks the
@@ -210,29 +227,29 @@ struct NodeBuilderContext {
/// constructed nodes) but did not have any outgoing transitions added.
class NodeBuilder {
virtual void anchor();
+
protected:
const NodeBuilderContext &C;
/// Specifies if the builder results have been finalized. For example, if it
/// is set to false, autotransitions are yet to be generated.
bool Finalized;
- bool HasGeneratedNodes;
- /// \brief The frontier set - a set of nodes which need to be propagated after
+
+ bool HasGeneratedNodes = false;
+
+ /// The frontier set - a set of nodes which need to be propagated after
/// the builder dies.
ExplodedNodeSet &Frontier;
- /// Checkes if the results are ready.
+ /// Checks if the results are ready.
virtual bool checkResults() {
- if (!Finalized)
- return false;
- return true;
+ return Finalized;
}
bool hasNoSinksInFrontier() {
- for (iterator I = Frontier.begin(), E = Frontier.end(); I != E; ++I) {
- if ((*I)->isSink())
+ for (const auto I : Frontier)
+ if (I->isSink())
return false;
- }
return true;
}
@@ -247,27 +264,27 @@ protected:
public:
NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
const NodeBuilderContext &Ctx, bool F = true)
- : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
+ : C(Ctx), Finalized(F), Frontier(DstSet) {
Frontier.Add(SrcNode);
}
NodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
const NodeBuilderContext &Ctx, bool F = true)
- : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
+ : C(Ctx), Finalized(F), Frontier(DstSet) {
Frontier.insert(SrcSet);
assert(hasNoSinksInFrontier());
}
- virtual ~NodeBuilder() {}
+ virtual ~NodeBuilder() = default;
- /// \brief Generates a node in the ExplodedGraph.
+ /// Generates a node in the ExplodedGraph.
ExplodedNode *generateNode(const ProgramPoint &PP,
ProgramStateRef State,
ExplodedNode *Pred) {
return generateNodeImpl(PP, State, Pred, false);
}
- /// \brief Generates a sink in the ExplodedGraph.
+ /// Generates a sink in the ExplodedGraph.
///
/// When a node is marked as sink, the exploration from the node is stopped -
/// the node becomes the last node on the path and certain kinds of bugs are
@@ -284,14 +301,16 @@ public:
return Frontier;
}
- typedef ExplodedNodeSet::iterator iterator;
- /// \brief Iterators through the results frontier.
- inline iterator begin() {
+ using iterator = ExplodedNodeSet::iterator;
+
+ /// Iterators through the results frontier.
+ iterator begin() {
finalizeResults();
assert(checkResults());
return Frontier.begin();
}
- inline iterator end() {
+
+ iterator end() {
finalizeResults();
return Frontier.end();
}
@@ -300,18 +319,20 @@ public:
bool hasGeneratedNodes() { return HasGeneratedNodes; }
void takeNodes(const ExplodedNodeSet &S) {
- for (ExplodedNodeSet::iterator I = S.begin(), E = S.end(); I != E; ++I )
- Frontier.erase(*I);
+ for (const auto I : S)
+ Frontier.erase(I);
}
+
void takeNodes(ExplodedNode *N) { Frontier.erase(N); }
void addNodes(const ExplodedNodeSet &S) { Frontier.insert(S); }
void addNodes(ExplodedNode *N) { Frontier.Add(N); }
};
/// \class NodeBuilderWithSinks
-/// \brief This node builder keeps track of the generated sink nodes.
+/// This node builder keeps track of the generated sink nodes.
class NodeBuilderWithSinks: public NodeBuilder {
void anchor() override;
+
protected:
SmallVector<ExplodedNode*, 2> sinksGenerated;
ProgramPoint &Location;
@@ -319,7 +340,7 @@ protected:
public:
NodeBuilderWithSinks(ExplodedNode *Pred, ExplodedNodeSet &DstSet,
const NodeBuilderContext &Ctx, ProgramPoint &L)
- : NodeBuilder(Pred, DstSet, Ctx), Location(L) {}
+ : NodeBuilder(Pred, DstSet, Ctx), Location(L) {}
ExplodedNode *generateNode(ProgramStateRef State,
ExplodedNode *Pred,
@@ -343,20 +364,20 @@ public:
};
/// \class StmtNodeBuilder
-/// \brief This builder class is useful for generating nodes that resulted from
+/// This builder class is useful for generating nodes that resulted from
/// visiting a statement. The main difference from its parent NodeBuilder is
/// that it creates a statement specific ProgramPoint.
class StmtNodeBuilder: public NodeBuilder {
NodeBuilder *EnclosingBldr;
-public:
- /// \brief Constructs a StmtNodeBuilder. If the builder is going to process
+public:
+ /// Constructs a StmtNodeBuilder. If the builder is going to process
/// nodes currently owned by another builder(with larger scope), use
/// Enclosing builder to transfer ownership.
StmtNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
const NodeBuilderContext &Ctx,
NodeBuilder *Enclosing = nullptr)
- : NodeBuilder(SrcNode, DstSet, Ctx), EnclosingBldr(Enclosing) {
+ : NodeBuilder(SrcNode, DstSet, Ctx), EnclosingBldr(Enclosing) {
if (EnclosingBldr)
EnclosingBldr->takeNodes(SrcNode);
}
@@ -364,11 +385,10 @@ public:
StmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
const NodeBuilderContext &Ctx,
NodeBuilder *Enclosing = nullptr)
- : NodeBuilder(SrcSet, DstSet, Ctx), EnclosingBldr(Enclosing) {
+ : NodeBuilder(SrcSet, DstSet, Ctx), EnclosingBldr(Enclosing) {
if (EnclosingBldr)
- for (ExplodedNodeSet::iterator I = SrcSet.begin(),
- E = SrcSet.end(); I != E; ++I )
- EnclosingBldr->takeNodes(*I);
+ for (const auto I : SrcSet)
+ EnclosingBldr->takeNodes(I);
}
~StmtNodeBuilder() override;
@@ -397,22 +417,23 @@ public:
}
};
-/// \brief BranchNodeBuilder is responsible for constructing the nodes
+/// BranchNodeBuilder is responsible for constructing the nodes
/// corresponding to the two branches of the if statement - true and false.
class BranchNodeBuilder: public NodeBuilder {
- void anchor() override;
const CFGBlock *DstT;
const CFGBlock *DstF;
bool InFeasibleTrue;
bool InFeasibleFalse;
+ void anchor() override;
+
public:
BranchNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
const NodeBuilderContext &C,
const CFGBlock *dstT, const CFGBlock *dstF)
- : NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF),
- InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
+ : NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF),
+ InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
// The branch node builder does not generate autotransitions.
// If there are no successors it means that both branches are infeasible.
takeNodes(SrcNode);
@@ -421,8 +442,8 @@ public:
BranchNodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
const NodeBuilderContext &C,
const CFGBlock *dstT, const CFGBlock *dstF)
- : NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF),
- InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
+ : NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF),
+ InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
takeNodes(SrcSet);
}
@@ -455,15 +476,16 @@ class IndirectGotoNodeBuilder {
public:
IndirectGotoNodeBuilder(ExplodedNode *pred, const CFGBlock *src,
const Expr *e, const CFGBlock *dispatch, CoreEngine* eng)
- : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
+ : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
class iterator {
+ friend class IndirectGotoNodeBuilder;
+
CFGBlock::const_succ_iterator I;
- friend class IndirectGotoNodeBuilder;
iterator(CFGBlock::const_succ_iterator i) : I(i) {}
- public:
+ public:
iterator &operator++() { ++I; return *this; }
bool operator!=(const iterator &X) const { return I != X.I; }
@@ -501,12 +523,13 @@ class SwitchNodeBuilder {
public:
SwitchNodeBuilder(ExplodedNode *pred, const CFGBlock *src,
const Expr *condition, CoreEngine* eng)
- : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
+ : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
class iterator {
+ friend class SwitchNodeBuilder;
+
CFGBlock::const_succ_reverse_iterator I;
- friend class SwitchNodeBuilder;
iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {}
public:
@@ -545,7 +568,8 @@ public:
}
};
-} // end ento namespace
-} // end clang namespace
+} // namespace ento
+
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
index e13c6410c7be9..092e23ce73c8b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
@@ -14,7 +14,7 @@
namespace clang {
namespace ento {
-/// \brief Stores the currently inferred strictest bound on the runtime type
+/// Stores the currently inferred strictest bound on the runtime type
/// of a region in a given state along the analysis path.
class DynamicTypeInfo {
private:
@@ -27,13 +27,13 @@ public:
DynamicTypeInfo(QualType WithType, bool CanBeSub = true)
: T(WithType), CanBeASubClass(CanBeSub) {}
- /// \brief Return false if no dynamic type info is available.
+ /// Return false if no dynamic type info is available.
bool isValid() const { return !T.isNull(); }
- /// \brief Returns the currently inferred upper bound on the runtime type.
+ /// Returns the currently inferred upper bound on the runtime type.
QualType getType() const { return T; }
- /// \brief Returns false if the type information is precise (the type T is
+ /// Returns false if the type information is precise (the type T is
/// the only type in the lattice), true otherwise.
bool canBeASubClass() const { return CanBeASubClass; }
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
index 555191d997099..2f8ead0746cac 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
@@ -1,4 +1,4 @@
-//== DynamicTypeMap.h - Dynamic type map ----------------------- -*- C++ -*--=//
+//===- DynamicTypeMap.h - Dynamic type map ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,19 +13,26 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H
-#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "llvm/ADT/ImmutableMap.h"
+#include "clang/AST/Type.h"
namespace clang {
namespace ento {
+class MemRegion;
+
/// The GDM component containing the dynamic type info. This is a map from a
/// symbol to its most likely type.
struct DynamicTypeMap {};
-typedef llvm::ImmutableMap<const MemRegion *, DynamicTypeInfo>
- DynamicTypeMapImpl;
+
+using DynamicTypeMapImpl =
+ llvm::ImmutableMap<const MemRegion *, DynamicTypeInfo>;
+
template <>
struct ProgramStateTrait<DynamicTypeMap>
: public ProgramStatePartialTrait<DynamicTypeMapImpl> {
@@ -35,15 +42,15 @@ struct ProgramStateTrait<DynamicTypeMap>
}
};
-/// \brief Get dynamic type information for a region.
+/// Get dynamic type information for a region.
DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State,
const MemRegion *Reg);
-/// \brief Set dynamic type information of the region; return the new state.
+/// Set dynamic type information of the region; return the new state.
ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *Reg,
DynamicTypeInfo NewTy);
-/// \brief Set dynamic type information of the region; return the new state.
+/// Set dynamic type information of the region; return the new state.
inline ProgramStateRef setDynamicTypeInfo(ProgramStateRef State,
const MemRegion *Reg, QualType NewTy,
bool CanBeSubClassed = true) {
@@ -51,7 +58,10 @@ inline ProgramStateRef setDynamicTypeInfo(ProgramStateRef State,
DynamicTypeInfo(NewTy, CanBeSubClassed));
}
-} // ento
-} // clang
+void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out,
+ const char *NL, const char *Sep);
+
+} // namespace ento
+} // namespace clang
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
index c63ed4a013aa6..d49aa81bc9585 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -1,4 +1,4 @@
-//== Environment.h - Map from Stmt* to Locations/Values ---------*- C++ -*--==//
+//===- Environment.h - Map from Stmt* to Locations/Values -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,16 +15,17 @@
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/ADT/ImmutableMap.h"
+#include <utility>
namespace clang {
-class LiveVariables;
+class Stmt;
namespace ento {
-class EnvironmentManager;
class SValBuilder;
class SymbolReaper;
@@ -32,7 +33,7 @@ class SymbolReaper;
/// This allows the environment to manage context-sensitive bindings,
/// which is essentially for modeling recursive function analysis, among
/// other things.
-class EnvironmentEntry : public std::pair<const Stmt*,
+class EnvironmentEntry : public std::pair<const Stmt *,
const StackFrameContext *> {
public:
EnvironmentEntry(const Stmt *s, const LocationContext *L);
@@ -57,19 +58,17 @@ class Environment {
private:
friend class EnvironmentManager;
- // Type definitions.
- typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy;
+ using BindingsTy = llvm::ImmutableMap<EnvironmentEntry, SVal>;
- // Data.
BindingsTy ExprBindings;
- Environment(BindingsTy eb)
- : ExprBindings(eb) {}
+ Environment(BindingsTy eb) : ExprBindings(eb) {}
SVal lookupExpr(const EnvironmentEntry &E) const;
public:
- typedef BindingsTy::iterator iterator;
+ using iterator = BindingsTy::iterator;
+
iterator begin() const { return ExprBindings.begin(); }
iterator end() const { return ExprBindings.end(); }
@@ -92,21 +91,19 @@ public:
bool operator==(const Environment& RHS) const {
return ExprBindings == RHS.ExprBindings;
}
-
- void print(raw_ostream &Out, const char *NL, const char *Sep) const;
-
-private:
- void printAux(raw_ostream &Out, bool printLocations,
- const char *NL, const char *Sep) const;
+
+ void print(raw_ostream &Out, const char *NL, const char *Sep,
+ const LocationContext *WithLC = nullptr) const;
};
class EnvironmentManager {
private:
- typedef Environment::BindingsTy::Factory FactoryTy;
+ using FactoryTy = Environment::BindingsTy::Factory;
+
FactoryTy F;
public:
- EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
+ EnvironmentManager(llvm::BumpPtrAllocator &Allocator) : F(Allocator) {}
Environment getInitialEnvironment() {
return Environment(F.getEmptyMap());
@@ -121,8 +118,8 @@ public:
ProgramStateRef state);
};
-} // end GR namespace
+} // namespace ento
-} // end clang namespace
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index dcea5e461d27c..c12198db6598d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -1,4 +1,4 @@
-//=-- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -*- C++ -*-------==//
+//===- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,17 +19,25 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
-#include "clang/AST/Decl.h"
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Analysis/Support/BumpVector.h"
+#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include <cassert>
+#include <cstdint>
#include <memory>
#include <utility>
#include <vector>
@@ -37,6 +45,10 @@
namespace clang {
class CFG;
+class Decl;
+class Expr;
+class ParentMap;
+class Stmt;
namespace ento {
@@ -52,13 +64,13 @@ class ExplodedGraph;
// successors to it at any time after creating it.
class ExplodedNode : public llvm::FoldingSetNode {
- friend class ExplodedGraph;
- friend class CoreEngine;
- friend class NodeBuilder;
friend class BranchNodeBuilder;
+ friend class CoreEngine;
+ friend class EndOfFunctionNodeBuilder;
+ friend class ExplodedGraph;
friend class IndirectGotoNodeBuilder;
+ friend class NodeBuilder;
friend class SwitchNodeBuilder;
- friend class EndOfFunctionNodeBuilder;
/// Efficiently stores a list of ExplodedNodes, or an optional flag.
///
@@ -135,7 +147,7 @@ public:
}
const StackFrameContext *getStackFrame() const {
- return getLocationContext()->getCurrentStackFrame();
+ return getLocation().getStackFrame();
}
const Decl &getCodeDecl() const { return *getLocationContext()->getDecl(); }
@@ -156,6 +168,11 @@ public:
return Location.getAs<T>();
}
+ /// Get the value of an arbitrary expression at this node.
+ SVal getSVal(const Stmt *S) const {
+ return getState()->getSVal(S, getLocationContext());
+ }
+
static void Profile(llvm::FoldingSetNodeID &ID,
const ProgramPoint &Loc,
const ProgramStateRef &state,
@@ -198,10 +215,10 @@ public:
}
// Iterators over successor and predecessor vertices.
- typedef ExplodedNode* const * succ_iterator;
- typedef const ExplodedNode* const * const_succ_iterator;
- typedef ExplodedNode* const * pred_iterator;
- typedef const ExplodedNode* const * const_pred_iterator;
+ using succ_iterator = ExplodedNode * const *;
+ using const_succ_iterator = const ExplodedNode * const *;
+ using pred_iterator = ExplodedNode * const *;
+ using const_pred_iterator = const ExplodedNode * const *;
pred_iterator pred_begin() { return Preds.begin(); }
pred_iterator pred_end() { return Preds.end(); }
@@ -226,10 +243,10 @@ public:
// For debugging.
public:
-
class Auditor {
public:
virtual ~Auditor();
+
virtual void AddEdge(ExplodedNode *Src, ExplodedNode *Dst) = 0;
};
@@ -240,15 +257,15 @@ private:
void replacePredecessor(ExplodedNode *node) { Preds.replaceNode(node); }
};
-typedef llvm::DenseMap<const ExplodedNode *, const ExplodedNode *>
- InterExplodedGraphMap;
+using InterExplodedGraphMap =
+ llvm::DenseMap<const ExplodedNode *, const ExplodedNode *>;
class ExplodedGraph {
protected:
friend class CoreEngine;
// Type definitions.
- typedef std::vector<ExplodedNode *> NodeVector;
+ using NodeVector = std::vector<ExplodedNode *>;
/// The roots of the simulation graph. Usually there will be only
/// one, but clients are free to establish multiple subgraphs within a single
@@ -268,7 +285,7 @@ protected:
BumpVectorContext BVC;
/// NumNodes - The number of nodes in the graph.
- unsigned NumNodes;
+ unsigned NumNodes = 0;
/// A list of recently allocated nodes that can potentially be recycled.
NodeVector ChangedNodes;
@@ -279,14 +296,16 @@ protected:
/// Determines how often nodes are reclaimed.
///
/// If this is 0, nodes will never be reclaimed.
- unsigned ReclaimNodeInterval;
+ unsigned ReclaimNodeInterval = 0;
/// Counter to determine when to reclaim nodes.
unsigned ReclaimCounter;
public:
+ ExplodedGraph();
+ ~ExplodedGraph();
- /// \brief Retrieve the node associated with a (Location,State) pair,
+ /// Retrieve the node associated with a (Location,State) pair,
/// where the 'Location' is a ProgramPoint in the CFG. If no node for
/// this pair exists, it is created. IsNew is set to true if
/// the node was freshly created.
@@ -294,7 +313,7 @@ public:
bool IsSink = false,
bool* IsNew = nullptr);
- /// \brief Create a node for a (Location, State) pair,
+ /// Create a node for a (Location, State) pair,
/// but don't store it for deduplication later. This
/// is useful when copying an already completed
/// ExplodedGraph for further processing.
@@ -318,10 +337,6 @@ public:
return V;
}
- ExplodedGraph();
-
- ~ExplodedGraph();
-
unsigned num_roots() const { return Roots.size(); }
unsigned num_eops() const { return EndNodes.size(); }
@@ -331,14 +346,14 @@ public:
void reserve(unsigned NodeCount) { Nodes.reserve(NodeCount); }
// Iterators.
- typedef ExplodedNode NodeTy;
- typedef llvm::FoldingSet<ExplodedNode> AllNodesTy;
- typedef NodeVector::iterator roots_iterator;
- typedef NodeVector::const_iterator const_roots_iterator;
- typedef NodeVector::iterator eop_iterator;
- typedef NodeVector::const_iterator const_eop_iterator;
- typedef AllNodesTy::iterator node_iterator;
- typedef AllNodesTy::const_iterator const_node_iterator;
+ using NodeTy = ExplodedNode;
+ using AllNodesTy = llvm::FoldingSet<ExplodedNode>;
+ using roots_iterator = NodeVector::iterator;
+ using const_roots_iterator = NodeVector::const_iterator;
+ using eop_iterator = NodeVector::iterator;
+ using const_eop_iterator = NodeVector::const_iterator;
+ using node_iterator = AllNodesTy::iterator;
+ using const_node_iterator = AllNodesTy::const_iterator;
node_iterator nodes_begin() { return Nodes.begin(); }
@@ -367,7 +382,7 @@ public:
llvm::BumpPtrAllocator & getAllocator() { return BVC.getAllocator(); }
BumpVectorContext &getNodeAllocator() { return BVC; }
- typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap;
+ using NodeMap = llvm::DenseMap<const ExplodedNode *, ExplodedNode *>;
/// Creates a trimmed version of the graph that only contains paths leading
/// to the given nodes.
@@ -394,7 +409,7 @@ public:
/// was called.
void reclaimRecentlyAllocatedNodes();
- /// \brief Returns true if nodes for the given expression kind are always
+ /// Returns true if nodes for the given expression kind are always
/// kept around.
static bool isInterestingLValueExpr(const Expr *Ex);
@@ -404,29 +419,30 @@ private:
};
class ExplodedNodeSet {
- typedef llvm::SmallSetVector<ExplodedNode*, 4> ImplTy;
+ using ImplTy = llvm::SmallSetVector<ExplodedNode *, 4>;
ImplTy Impl;
public:
ExplodedNodeSet(ExplodedNode *N) {
- assert (N && !static_cast<ExplodedNode*>(N)->isSink());
+ assert(N && !static_cast<ExplodedNode*>(N)->isSink());
Impl.insert(N);
}
- ExplodedNodeSet() {}
+ ExplodedNodeSet() = default;
- inline void Add(ExplodedNode *N) {
+ void Add(ExplodedNode *N) {
if (N && !static_cast<ExplodedNode*>(N)->isSink()) Impl.insert(N);
}
- typedef ImplTy::iterator iterator;
- typedef ImplTy::const_iterator const_iterator;
+ using iterator = ImplTy::iterator;
+ using const_iterator = ImplTy::const_iterator;
unsigned size() const { return Impl.size(); }
bool empty() const { return Impl.empty(); }
bool erase(ExplodedNode *N) { return Impl.remove(N); }
void clear() { Impl.clear(); }
+
void insert(const ExplodedNodeSet &S) {
assert(&S != this);
if (empty())
@@ -435,24 +451,25 @@ public:
Impl.insert(S.begin(), S.end());
}
- inline iterator begin() { return Impl.begin(); }
- inline iterator end() { return Impl.end(); }
+ iterator begin() { return Impl.begin(); }
+ iterator end() { return Impl.end(); }
- inline const_iterator begin() const { return Impl.begin(); }
- inline const_iterator end() const { return Impl.end(); }
+ const_iterator begin() const { return Impl.begin(); }
+ const_iterator end() const { return Impl.end(); }
};
-} // end GR namespace
+} // namespace ento
-} // end clang namespace
+} // namespace clang
// GraphTraits
namespace llvm {
+
template<> struct GraphTraits<clang::ento::ExplodedNode*> {
- typedef clang::ento::ExplodedNode *NodeRef;
- typedef clang::ento::ExplodedNode::succ_iterator ChildIteratorType;
- typedef llvm::df_iterator<NodeRef> nodes_iterator;
+ using NodeRef = clang::ento::ExplodedNode *;
+ using ChildIteratorType = clang::ento::ExplodedNode::succ_iterator;
+ using nodes_iterator = llvm::df_iterator<NodeRef>;
static NodeRef getEntryNode(NodeRef N) { return N; }
@@ -466,9 +483,9 @@ namespace llvm {
};
template<> struct GraphTraits<const clang::ento::ExplodedNode*> {
- typedef const clang::ento::ExplodedNode *NodeRef;
- typedef clang::ento::ExplodedNode::const_succ_iterator ChildIteratorType;
- typedef llvm::df_iterator<NodeRef> nodes_iterator;
+ using NodeRef = const clang::ento::ExplodedNode *;
+ using ChildIteratorType = clang::ento::ExplodedNode::const_succ_iterator;
+ using nodes_iterator = llvm::df_iterator<NodeRef>;
static NodeRef getEntryNode(NodeRef N) { return N; }
@@ -481,6 +498,6 @@ namespace llvm {
static nodes_iterator nodes_end(NodeRef N) { return df_end(N); }
};
-} // end llvm namespace
+} // namespace llvm
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 712cd6361e118..25849e94c8ff1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -1,4 +1,4 @@
-//===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=//
+//===- ExprEngine.h - Path-Sensitive Expression-Level Dataflow --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,32 +18,68 @@
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h"
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
+#include "llvm/ADT/ArrayRef.h"
+#include <cassert>
+#include <utility>
namespace clang {
class AnalysisDeclContextManager;
+class AnalyzerOptions;
+class ASTContext;
+class ConstructionContext;
+class CXXBindTemporaryExpr;
class CXXCatchStmt;
class CXXConstructExpr;
class CXXDeleteExpr;
class CXXNewExpr;
-class CXXTemporaryObjectExpr;
class CXXThisExpr;
+class Decl;
+class DeclStmt;
+class GCCAsmStmt;
+class LambdaExpr;
+class LocationContext;
class MaterializeTemporaryExpr;
+class MSAsmStmt;
+class NamedDecl;
class ObjCAtSynchronizedStmt;
class ObjCForCollectionStmt;
+class ObjCIvarRefExpr;
+class ObjCMessageExpr;
+class ReturnStmt;
+class Stmt;
+
+namespace cross_tu {
+
+class CrossTranslationUnitContext;
+
+} // namespace cross_tu
namespace ento {
-class AnalysisManager;
+class BasicValueFactory;
class CallEvent;
-class CXXConstructorCall;
+class CheckerManager;
+class ConstraintManager;
+class CXXTempObjectRegion;
+class MemRegion;
+class RegionAndSymbolInvalidationTraits;
+class SymbolManager;
class ExprEngine : public SubEngine {
public:
@@ -51,11 +87,35 @@ public:
enum InliningModes {
/// Follow the default settings for inlining callees.
Inline_Regular = 0,
+
/// Do minimal inlining of callees.
Inline_Minimal = 0x1
};
+ /// Hints for figuring out of a call should be inlined during evalCall().
+ struct EvalCallOptions {
+ /// This call is a constructor or a destructor for which we do not currently
+ /// compute the this-region correctly.
+ bool IsCtorOrDtorWithImproperlyModeledTargetRegion = false;
+
+ /// This call is a constructor or a destructor for a single element within
+ /// an array, a part of array construction or destruction.
+ bool IsArrayCtorOrDtor = false;
+
+ /// This call is a constructor or a destructor of a temporary value.
+ bool IsTemporaryCtorOrDtor = false;
+
+ /// This call is a constructor for a temporary that is lifetime-extended
+ /// by binding it to a reference-type field within an aggregate,
+ /// for example 'A { const C &c; }; A a = { C() };'
+ bool IsTemporaryLifetimeExtendedViaAggregate = false;
+
+ EvalCallOptions() {}
+ };
+
private:
+ cross_tu::CrossTranslationUnitContext &CTU;
+
AnalysisManager &AMgr;
AnalysisDeclContextManager &AnalysisDeclContexts;
@@ -63,19 +123,19 @@ private:
CoreEngine Engine;
/// G - the simulation graph.
- ExplodedGraph& G;
+ ExplodedGraph &G;
/// StateMgr - Object that manages the data for all created states.
ProgramStateManager StateMgr;
/// SymMgr - Object that manages the symbol information.
- SymbolManager& SymMgr;
+ SymbolManager &SymMgr;
/// svalBuilder - SValBuilder object that creates SVals from expressions.
SValBuilder &svalBuilder;
- unsigned int currStmtIdx;
- const NodeBuilderContext *currBldrCtx;
+ unsigned int currStmtIdx = 0;
+ const NodeBuilderContext *currBldrCtx = nullptr;
/// Helper object to determine if an Objective-C message expression
/// implicitly never returns.
@@ -97,10 +157,9 @@ private:
InliningModes HowToInline;
public:
- ExprEngine(AnalysisManager &mgr, bool gcEnabled,
- SetOfConstDecls *VisitedCalleesIn,
- FunctionSummariesTy *FS,
- InliningModes HowToInlineIn);
+ ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr,
+ bool gcEnabled, SetOfConstDecls *VisitedCalleesIn,
+ FunctionSummariesTy *FS, InliningModes HowToInlineIn);
~ExprEngine() override;
@@ -130,7 +189,12 @@ public:
SValBuilder &getSValBuilder() { return svalBuilder; }
- BugReporter& getBugReporter() { return BR; }
+ BugReporter &getBugReporter() { return BR; }
+
+ cross_tu::CrossTranslationUnitContext *
+ getCrossTranslationUnitContext() override {
+ return &CTU;
+ }
const NodeBuilderContext &getBuilderContext() {
assert(currBldrCtx);
@@ -150,16 +214,16 @@ public:
/// Visualize a trimmed ExplodedGraph that only contains paths to the given
/// nodes.
- void ViewGraph(ArrayRef<const ExplodedNode*> Nodes);
+ void ViewGraph(ArrayRef<const ExplodedNode *> Nodes);
/// getInitialState - Return the initial state used for the root vertex
/// in the ExplodedGraph.
ProgramStateRef getInitialState(const LocationContext *InitLoc) override;
- ExplodedGraph& getGraph() { return G; }
- const ExplodedGraph& getGraph() const { return G; }
+ ExplodedGraph &getGraph() { return G; }
+ const ExplodedGraph &getGraph() const { return G; }
- /// \brief Run the analyzer's garbage collection - remove dead symbols and
+ /// Run the analyzer's garbage collection - remove dead symbols and
/// bindings from the state.
///
/// Checkers can participate in this process with two callbacks:
@@ -194,7 +258,7 @@ public:
void processCFGElement(const CFGElement E, ExplodedNode *Pred,
unsigned StmtIdx, NodeBuilderContext *Ctx) override;
- void ProcessStmt(const CFGStmt S, ExplodedNode *Pred);
+ void ProcessStmt(const Stmt *S, ExplodedNode *Pred);
void ProcessLoopExit(const Stmt* S, ExplodedNode *Pred);
@@ -299,25 +363,26 @@ public:
const CallEvent *Call) override;
/// printState - Called by ProgramStateManager to print checker-specific data.
- void printState(raw_ostream &Out, ProgramStateRef State,
- const char *NL, const char *Sep) override;
+ void printState(raw_ostream &Out, ProgramStateRef State, const char *NL,
+ const char *Sep,
+ const LocationContext *LCtx = nullptr) override;
- ProgramStateManager& getStateManager() override { return StateMgr; }
+ ProgramStateManager &getStateManager() override { return StateMgr; }
- StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
+ StoreManager &getStoreManager() { return StateMgr.getStoreManager(); }
- ConstraintManager& getConstraintManager() {
+ ConstraintManager &getConstraintManager() {
return StateMgr.getConstraintManager();
}
// FIXME: Remove when we migrate over to just using SValBuilder.
- BasicValueFactory& getBasicVals() {
+ BasicValueFactory &getBasicVals() {
return StateMgr.getBasicVals();
}
// FIXME: Remove when we migrate over to just using ValueManager.
- SymbolManager& getSymbolManager() { return SymMgr; }
- const SymbolManager& getSymbolManager() const { return SymMgr; }
+ SymbolManager &getSymbolManager() { return SymMgr; }
+ const SymbolManager &getSymbolManager() const { return SymMgr; }
// Functions for external checking of whether we have unfinished work
bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
@@ -363,7 +428,7 @@ public:
/// VisitCast - Transfer function logic for all casts (implicit and explicit).
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
+ ExplodedNodeSet &Dst);
/// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
@@ -390,9 +455,9 @@ public:
/// VisitMemberExpr - Transfer function for member expressions.
void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
+ ExplodedNodeSet &Dst);
- /// VisitMemberExpr - Transfer function for builtin atomic expressions
+ /// VisitAtomicExpr - Transfer function for builtin atomic expressions
void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
@@ -422,7 +487,7 @@ public:
/// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
+ ExplodedNode *Pred, ExplodedNodeSet &Dst);
/// VisitUnaryOperator - Transfer function logic for unary operators.
void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred,
@@ -448,7 +513,8 @@ public:
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest,
const Stmt *S, bool IsBaseDtor,
- ExplodedNode *Pred, ExplodedNodeSet &Dst);
+ ExplodedNode *Pred, ExplodedNodeSet &Dst,
+ const EvalCallOptions &Options);
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
ExplodedNode *Pred,
@@ -471,7 +537,7 @@ public:
void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
const Expr *Ex);
- std::pair<const ProgramPointTag *, const ProgramPointTag*>
+ static std::pair<const ProgramPointTag *, const ProgramPointTag *>
geteagerlyAssumeBinOpBifurcationTags();
SVal evalMinus(SVal X) {
@@ -499,7 +565,6 @@ public:
StmtNodeBuilder &Bldr);
public:
-
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
NonLoc L, NonLoc R, QualType T) {
return svalBuilder.evalBinOpNN(state, op, L, R, T);
@@ -539,6 +604,11 @@ protected:
const CallEvent *Call,
RegionAndSymbolInvalidationTraits &ITraits) override;
+ /// A simple wrapper when you only need to notify checkers of pointer-escape
+ /// of a single value.
+ ProgramStateRef escapeValue(ProgramStateRef State, SVal V,
+ PointerEscapeKind K) const;
+
public:
// FIXME: 'tag' should be removed, and a LocationContext should be used
// instead.
@@ -561,7 +631,13 @@ public:
ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val,
const ProgramPointTag *tag = nullptr);
- /// \brief Create a new state in which the call return value is binded to the
+ /// Return the CFG element corresponding to the worklist element
+ /// that is currently being processed by ExprEngine.
+ CFGElement getCurrentCFGElement() {
+ return (*currBldrCtx->getBlock())[currStmtIdx];
+ }
+
+ /// Create a new state in which the call return value is binded to the
/// call origin expression.
ProgramStateRef bindReturnValue(const CallEvent &Call,
const LocationContext *LCtx,
@@ -572,9 +648,11 @@ public:
void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
const CallEvent &Call);
- /// \brief Default implementation of call evaluation.
+ /// Default implementation of call evaluation.
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred,
- const CallEvent &Call);
+ const CallEvent &Call,
+ const EvalCallOptions &CallOpts = {});
+
private:
void evalLoadCommon(ExplodedNodeSet &Dst,
const Expr *NodeEx, /* Eventually will be a CFGStmt */
@@ -598,19 +676,33 @@ private:
void examineStackFrames(const Decl *D, const LocationContext *LCtx,
bool &IsRecursive, unsigned &StackDepth);
+ enum CallInlinePolicy {
+ CIP_Allowed,
+ CIP_DisallowedOnce,
+ CIP_DisallowedAlways
+ };
+
+ /// See if a particular call should be inlined, by only looking
+ /// at the call event and the current state of analysis.
+ CallInlinePolicy mayInlineCallKind(const CallEvent &Call,
+ const ExplodedNode *Pred,
+ AnalyzerOptions &Opts,
+ const EvalCallOptions &CallOpts);
+
/// Checks our policies and decides weither the given call should be inlined.
bool shouldInlineCall(const CallEvent &Call, const Decl *D,
- const ExplodedNode *Pred);
+ const ExplodedNode *Pred,
+ const EvalCallOptions &CallOpts = {});
bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
ExplodedNode *Pred, ProgramStateRef State);
- /// \brief Conservatively evaluate call by invalidating regions and binding
+ /// Conservatively evaluate call by invalidating regions and binding
/// a conjured return value.
void conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
ExplodedNode *Pred, ProgramStateRef State);
- /// \brief Either inline or process the call conservatively (or both), based
+ /// Either inline or process the call conservatively (or both), based
/// on DynamicDispatchBifurcation data.
void BifurcateCall(const MemRegion *BifurReg,
const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
@@ -634,6 +726,17 @@ private:
const Expr *InitWithAdjustments,
const Expr *Result = nullptr);
+ /// Returns a region representing the first element of a (possibly
+ /// multi-dimensional) array, for the purposes of element construction or
+ /// destruction.
+ ///
+ /// On return, \p Ty will be set to the base type of the array.
+ ///
+ /// If the type is not an array type at all, the original value is returned.
+ /// Otherwise the "IsArray" flag is set.
+ static SVal makeZeroElementRegion(ProgramStateRef State, SVal LValue,
+ QualType &Ty, bool &IsArray);
+
/// For a DeclStmt or CXXInitCtorInitializer, walk backward in the current CFG
/// block to find the constructor expression that directly constructed into
/// the storage for this statement. Returns null if the constructor for this
@@ -641,20 +744,69 @@ private:
/// constructing into an existing region.
const CXXConstructExpr *findDirectConstructorForCurrentCFGElement();
- /// For a CXXConstructExpr, walk forward in the current CFG block to find the
- /// CFGElement for the DeclStmt or CXXInitCtorInitializer for which is
- /// directly constructed by this constructor. Returns None if the current
- /// constructor expression did not directly construct into an existing
- /// region.
- Optional<CFGElement> findElementDirectlyInitializedByCurrentConstructor();
-
- /// For a given constructor, look forward in the current CFG block to
- /// determine the region into which an object will be constructed by \p CE.
- /// Returns either a field or local variable region if the object will be
- /// directly constructed in an existing region or a temporary object region
- /// if not.
- const MemRegion *getRegionForConstructedObject(const CXXConstructExpr *CE,
- ExplodedNode *Pred);
+ /// Update the program state with all the path-sensitive information
+ /// that's necessary to perform construction of an object with a given
+ /// syntactic construction context. If the construction context is unavailable
+ /// or unusable for any reason, a dummy temporary region is returned, and the
+ /// IsConstructorWithImproperlyModeledTargetRegion flag is set in \p CallOpts.
+ /// Returns the updated program state and the new object's this-region.
+ std::pair<ProgramStateRef, SVal> prepareForObjectConstruction(
+ const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
+ const ConstructionContext *CC, EvalCallOptions &CallOpts);
+
+ /// Store the location of a C++ object corresponding to a statement
+ /// until the statement is actually encountered. For example, if a DeclStmt
+ /// has CXXConstructExpr as its initializer, the object would be considered
+ /// to be "under construction" between CXXConstructExpr and DeclStmt.
+ /// This allows, among other things, to keep bindings to variable's fields
+ /// made within the constructor alive until its declaration actually
+ /// goes into scope.
+ static ProgramStateRef addObjectUnderConstruction(
+ ProgramStateRef State,
+ llvm::PointerUnion<const Stmt *, const CXXCtorInitializer *> P,
+ const LocationContext *LC, SVal V);
+
+ /// Mark the object sa fully constructed, cleaning up the state trait
+ /// that tracks objects under construction.
+ static ProgramStateRef finishObjectConstruction(
+ ProgramStateRef State,
+ llvm::PointerUnion<const Stmt *, const CXXCtorInitializer *> P,
+ const LocationContext *LC);
+
+ /// If the given statement corresponds to an object under construction,
+ /// being part of its construciton context, retrieve that object's location.
+ static Optional<SVal> getObjectUnderConstruction(
+ ProgramStateRef State,
+ llvm::PointerUnion<const Stmt *, const CXXCtorInitializer *> P,
+ const LocationContext *LC);
+
+ /// If the given expression corresponds to a temporary that was used for
+ /// passing into an elidable copy/move constructor and that constructor
+ /// was actually elided, track that we also need to elide the destructor.
+ static ProgramStateRef elideDestructor(ProgramStateRef State,
+ const CXXBindTemporaryExpr *BTE,
+ const LocationContext *LC);
+
+ /// Stop tracking the destructor that corresponds to an elided constructor.
+ static ProgramStateRef
+ cleanupElidedDestructor(ProgramStateRef State,
+ const CXXBindTemporaryExpr *BTE,
+ const LocationContext *LC);
+
+ /// Returns true if the given expression corresponds to a temporary that
+ /// was constructed for passing into an elidable copy/move constructor
+ /// and that constructor was actually elided.
+ static bool isDestructorElided(ProgramStateRef State,
+ const CXXBindTemporaryExpr *BTE,
+ const LocationContext *LC);
+
+ /// Check if all objects under construction have been fully constructed
+ /// for the given context range (including FromLC, not including ToLC).
+ /// This is useful for assertions. Also checks if elided destructors
+ /// were cleaned up.
+ static bool areAllObjectsFullyConstructed(ProgramStateRef State,
+ const LocationContext *FromLC,
+ const LocationContext *ToLC);
};
/// Traits for storing the call processing policy inside GDM.
@@ -668,8 +820,8 @@ struct ProgramStateTrait<ReplayWithoutInlining> :
static void *GDMIndex() { static int index = 0; return &index; }
};
-} // end ento namespace
+} // namespace ento
-} // end clang namespace
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
index ce81c98c206b2..b70faa10f0b2c 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
@@ -1,4 +1,4 @@
-//== FunctionSummary.h - Stores summaries of functions. ------------*- C++ -*-//
+//===- FunctionSummary.h - Stores summaries of functions. -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,15 +18,18 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallBitVector.h"
+#include <cassert>
#include <deque>
+#include <utility>
namespace clang {
-
namespace ento {
-typedef std::deque<Decl*> SetOfDecls;
-typedef llvm::DenseSet<const Decl*> SetOfConstDecls;
+
+using SetOfDecls = std::deque<Decl *>;
+using SetOfConstDecls = llvm::DenseSet<const Decl *>;
class FunctionSummariesTy {
class FunctionSummary {
@@ -47,13 +50,12 @@ class FunctionSummariesTy {
/// The number of times the function has been inlined.
unsigned TimesInlined : 32;
- FunctionSummary() :
- TotalBasicBlocks(0),
- InlineChecked(0),
- TimesInlined(0) {}
+ FunctionSummary()
+ : TotalBasicBlocks(0), InlineChecked(0), MayInline(0),
+ TimesInlined(0) {}
};
- typedef llvm::DenseMap<const Decl *, FunctionSummary> MapTy;
+ using MapTy = llvm::DenseMap<const Decl *, FunctionSummary>;
MapTy Map;
public:
@@ -62,7 +64,8 @@ public:
if (I != Map.end())
return I;
- typedef std::pair<const Decl *, FunctionSummary> KVPair;
+ using KVPair = std::pair<const Decl *, FunctionSummary>;
+
I = Map.insert(KVPair(D, FunctionSummary())).first;
assert(I != Map.end());
return I;
@@ -132,9 +135,9 @@ public:
unsigned getTotalNumBasicBlocks();
unsigned getTotalNumVisitedBasicBlocks();
-
};
-}} // end clang ento namespaces
+} // namespace ento
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h
index 3168733e4258e..f494c5d6dab82 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h
@@ -22,7 +22,7 @@
namespace clang {
namespace ento {
-/// \brief Get the states that result from widening the loop.
+/// Get the states that result from widening the loop.
///
/// Widen the loop by invalidating anything that might be modified
/// by the loop body in any iteration.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 8ab6656230888..f3846eba6b963 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -1,4 +1,4 @@
-//== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==//
+//==- MemRegion.h - Abstract memory regions for static analysis -*- C++ -*--==//
//
// The LLVM Compiler Infrastructure
//
@@ -19,24 +19,39 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
-#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
+#include <cstdint>
+#include <limits>
#include <string>
+#include <utility>
namespace clang {
+class AnalysisDeclContext;
+class CXXRecordDecl;
+class Decl;
class LocationContext;
class StackFrameContext;
namespace ento {
class CodeTextRegion;
+class MemRegion;
class MemRegionManager;
class MemSpaceRegion;
class SValBuilder;
@@ -46,7 +61,7 @@ class VarRegion;
/// Represent a region's offset within the top level base region.
class RegionOffset {
/// The base region.
- const MemRegion *R;
+ const MemRegion *R = nullptr;
/// The bit offset within the base region. Can be negative.
int64_t Offset;
@@ -54,9 +69,9 @@ class RegionOffset {
public:
// We're using a const instead of an enumeration due to the size required;
// Visual Studio will only create enumerations of size int, not long long.
- static const int64_t Symbolic = INT64_MAX;
+ static const int64_t Symbolic = std::numeric_limits<int64_t>::max();
- RegionOffset() : R(nullptr) {}
+ RegionOffset() = default;
RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
const MemRegion *getRegion() const { return R; }
@@ -86,6 +101,7 @@ public:
private:
const Kind kind;
+ mutable Optional<RegionOffset> cachedOffset;
protected:
MemRegion(Kind k) : kind(k) {}
@@ -103,11 +119,12 @@ public:
const MemRegion *getBaseRegion() const;
/// Check if the region is a subregion of the given region.
+ /// Each region is a subregion of itself.
virtual bool isSubRegionOf(const MemRegion *R) const;
const MemRegion *StripCasts(bool StripBaseCasts = true) const;
- /// \brief If this is a symbolic region, returns the region. Otherwise,
+ /// If this is a symbolic region, returns the region. Otherwise,
/// goes up the base chain looking for the first symbolic base region.
const SymbolicRegion *getSymbolicBase() const;
@@ -122,24 +139,24 @@ public:
/// Compute the offset within the top level memory object.
RegionOffset getAsOffset() const;
- /// \brief Get a string representation of a region for debug use.
+ /// Get a string representation of a region for debug use.
std::string getString() const;
virtual void dumpToStream(raw_ostream &os) const;
void dump() const;
- /// \brief Returns true if this region can be printed in a user-friendly way.
+ /// Returns true if this region can be printed in a user-friendly way.
virtual bool canPrintPretty() const;
- /// \brief Print the region for use in diagnostics.
+ /// Print the region for use in diagnostics.
virtual void printPretty(raw_ostream &os) const;
- /// \brief Returns true if this region's textual representation can be used
+ /// Returns true if this region's textual representation can be used
/// as part of a larger expression.
virtual bool canPrintPrettyAsExpr() const;
- /// \brief Print the region as expression.
+ /// Print the region as expression.
///
/// When this region represents a subexpression, the method is for printing
/// an expression containing it.
@@ -151,7 +168,6 @@ public:
virtual bool isBoundable() const { return false; }
-
/// Get descriptive name for memory region. The name is obtained from
/// the variable/field declaration retrieved from the memory region.
/// Regions that point to an element of an array are returned as: "arr[0]".
@@ -162,7 +178,6 @@ public:
/// \returns variable name for memory region
std::string getDescriptiveName(bool UseQuotes = true) const;
-
/// Retrieve source range from memory region. The range retrieval
/// is based on the decl obtained from the memory region.
/// For a VarRegion the range of the base region is returned.
@@ -171,7 +186,7 @@ public:
/// The client is responsible for checking if the returned range is valid.
///
/// \returns source range for declaration retrieved from memory region
- clang::SourceRange sourceRange() const;
+ SourceRange sourceRange() const;
};
/// MemSpaceRegion - A memory region that represents a "memory space";
@@ -229,7 +244,7 @@ public:
}
};
-/// \brief The region of the static variables within the current CodeTextRegion
+/// The region of the static variables within the current CodeTextRegion
/// scope.
///
/// Currently, only the static locals are placed there, so we know that these
@@ -240,7 +255,7 @@ class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
const CodeTextRegion *CR;
StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
- : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
+ : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
assert(cr);
}
@@ -256,14 +271,14 @@ public:
}
};
-/// \brief The region for all the non-static global variables.
+/// The region for all the non-static global variables.
///
/// This class is further split into subclasses for efficient implementation of
/// invalidating a set of related global values as is done in
/// RegionStoreManager::invalidateRegions (instead of finding all the dependent
/// globals, we invalidate the whole parent region).
class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
- virtual void anchor() override;
+ void anchor() override;
protected:
NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
@@ -272,7 +287,6 @@ protected:
}
public:
-
static bool classof(const MemRegion *R) {
Kind k = R->getKind();
return k >= BEGIN_NON_STATIC_GLOBAL_MEMSPACES &&
@@ -280,16 +294,15 @@ public:
}
};
-/// \brief The region containing globals which are defined in system/external
+/// The region containing globals which are defined in system/external
/// headers and are considered modifiable by system calls (ex: errno).
class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
friend class MemRegionManager;
GlobalSystemSpaceRegion(MemRegionManager *mgr)
- : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
+ : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
public:
-
void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
@@ -297,7 +310,7 @@ public:
}
};
-/// \brief The region containing globals which are considered not to be modified
+/// The region containing globals which are considered not to be modified
/// or point to data which could be modified as a result of a function call
/// (system or internal). Ex: Const global scalars would be modeled as part of
/// this region. This region also includes most system globals since they have
@@ -306,10 +319,9 @@ class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
friend class MemRegionManager;
GlobalImmutableSpaceRegion(MemRegionManager *mgr)
- : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
+ : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
public:
-
void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
@@ -317,17 +329,16 @@ public:
}
};
-/// \brief The region containing globals which can be modified by calls to
+/// The region containing globals which can be modified by calls to
/// "internally" defined functions - (for now just) functions other then system
/// calls.
class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
friend class MemRegionManager;
GlobalInternalSpaceRegion(MemRegionManager *mgr)
- : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
+ : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
public:
-
void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
@@ -339,9 +350,9 @@ class HeapSpaceRegion : public MemSpaceRegion {
friend class MemRegionManager;
HeapSpaceRegion(MemRegionManager *mgr)
- : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
-public:
+ : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
+public:
void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
@@ -351,11 +362,11 @@ public:
class UnknownSpaceRegion : public MemSpaceRegion {
friend class MemRegionManager;
+
UnknownSpaceRegion(MemRegionManager *mgr)
: MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
public:
-
void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
@@ -370,7 +381,7 @@ class StackSpaceRegion : public MemSpaceRegion {
protected:
StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
- : MemSpaceRegion(mgr, k), SFC(sfc) {
+ : MemSpaceRegion(mgr, k), SFC(sfc) {
assert(classof(this));
assert(sfc);
}
@@ -388,10 +399,11 @@ public:
class StackLocalsSpaceRegion : public StackSpaceRegion {
friend class MemRegionManager;
+
StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
- : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
-public:
+ : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
+public:
void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
@@ -402,10 +414,11 @@ public:
class StackArgumentsSpaceRegion : public StackSpaceRegion {
private:
friend class MemRegionManager;
+
StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
- : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
-public:
+ : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
+public:
void dumpToStream(raw_ostream &os) const override;
static bool classof(const MemRegion *R) {
@@ -413,7 +426,6 @@ public:
}
};
-
/// SubRegion - A region that subsets another larger region. Most regions
/// are subclasses of SubRegion.
class SubRegion : public MemRegion {
@@ -421,6 +433,7 @@ class SubRegion : public MemRegion {
protected:
const MemRegion* superRegion;
+
SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
assert(classof(this));
assert(sReg);
@@ -454,8 +467,10 @@ public:
class AllocaRegion : public SubRegion {
friend class MemRegionManager;
- unsigned Cnt; // Block counter. Used to distinguish different pieces of
- // memory allocated by alloca at the same call site.
+ // Block counter. Used to distinguish different pieces of memory allocated by
+ // alloca at the same call site.
+ unsigned Cnt;
+
const Expr *Ex;
AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
@@ -467,7 +482,6 @@ class AllocaRegion : public SubRegion {
unsigned Cnt, const MemRegion *superRegion);
public:
-
const Expr *getExpr() const { return Ex; }
bool isBoundable() const override { return true; }
@@ -485,7 +499,7 @@ public:
/// TypedRegion - An abstract class representing regions that are typed.
class TypedRegion : public SubRegion {
- virtual void anchor() override;
+ void anchor() override;
protected:
TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
@@ -509,7 +523,7 @@ public:
/// TypedValueRegion - An abstract class representing regions having a typed value.
class TypedValueRegion : public TypedRegion {
- virtual void anchor() override;
+ void anchor() override;
protected:
TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
@@ -541,9 +555,8 @@ public:
}
};
-
class CodeTextRegion : public TypedRegion {
- virtual void anchor() override;
+ void anchor() override;
protected:
CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
@@ -566,7 +579,7 @@ class FunctionCodeRegion : public CodeTextRegion {
const NamedDecl *FD;
FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg)
- : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
+ : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
}
@@ -576,7 +589,7 @@ class FunctionCodeRegion : public CodeTextRegion {
public:
QualType getLocationType() const override {
const ASTContext &Ctx = getContext();
- if (const FunctionDecl *D = dyn_cast<FunctionDecl>(FD)) {
+ if (const auto *D = dyn_cast<FunctionDecl>(FD)) {
return Ctx.getPointerType(D->getType());
}
@@ -585,7 +598,7 @@ public:
// TODO: We might want to return a different type here (ex: id (*ty)(...))
// depending on how it is used.
- return QualType();
+ return {};
}
const NamedDecl *getDecl() const {
@@ -601,7 +614,6 @@ public:
}
};
-
/// BlockCodeRegion - A region that represents code texts of blocks (closures).
/// Blocks are represented with two kinds of regions. BlockCodeRegions
/// represent the "code", while BlockDataRegions represent instances of blocks,
@@ -657,15 +669,15 @@ class BlockDataRegion : public TypedRegion {
friend class MemRegionManager;
const BlockCodeRegion *BC;
- const LocationContext *LC; // Can be null */
+ const LocationContext *LC; // Can be null
unsigned BlockCount;
- void *ReferencedVars;
- void *OriginalVars;
+ void *ReferencedVars = nullptr;
+ void *OriginalVars = nullptr;
BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
unsigned count, const MemSpaceRegion *sreg)
: TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
- BlockCount(count), ReferencedVars(nullptr), OriginalVars(nullptr) {
+ BlockCount(count) {
assert(bc);
assert(lc);
assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
@@ -679,7 +691,7 @@ class BlockDataRegion : public TypedRegion {
public:
const BlockCodeRegion *getCodeRegion() const { return BC; }
-
+
const BlockDecl *getDecl() const { return BC->getDecl(); }
QualType getLocationType() const override { return BC->getLocationType(); }
@@ -687,14 +699,16 @@ public:
class referenced_vars_iterator {
const MemRegion * const *R;
const MemRegion * const *OriginalR;
+
public:
explicit referenced_vars_iterator(const MemRegion * const *r,
const MemRegion * const *originalR)
- : R(r), OriginalR(originalR) {}
+ : R(r), OriginalR(originalR) {}
const VarRegion *getCapturedRegion() const {
return cast<VarRegion>(*R);
}
+
const VarRegion *getOriginalRegion() const {
return cast<VarRegion>(*OriginalR);
}
@@ -703,10 +717,12 @@ public:
assert((R == nullptr) == (I.R == nullptr));
return I.R == R;
}
+
bool operator!=(const referenced_vars_iterator &I) const {
assert((R == nullptr) == (I.R == nullptr));
return I.R != R;
}
+
referenced_vars_iterator &operator++() {
++R;
++OriginalR;
@@ -728,6 +744,7 @@ public:
static bool classof(const MemRegion* R) {
return R->getKind() == BlockDataRegionKind;
}
+
private:
void LazyInitializeReferencedVars();
std::pair<const VarRegion *, const VarRegion *>
@@ -754,9 +771,7 @@ class SymbolicRegion : public SubRegion {
}
public:
- SymbolRef getSymbol() const {
- return sym;
- }
+ SymbolRef getSymbol() const { return sym; }
bool isBoundable() const override { return true; }
@@ -779,24 +794,21 @@ public:
class StringRegion : public TypedValueRegion {
friend class MemRegionManager;
- const StringLiteral* Str;
+ const StringLiteral *Str;
StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
: TypedValueRegion(sreg, StringRegionKind), Str(str) {
assert(str);
}
- static void ProfileRegion(llvm::FoldingSetNodeID& ID,
- const StringLiteral* Str,
- const MemRegion* superRegion);
+ static void ProfileRegion(llvm::FoldingSetNodeID &ID,
+ const StringLiteral *Str,
+ const MemRegion *superRegion);
public:
+ const StringLiteral *getStringLiteral() const { return Str; }
- const StringLiteral* getStringLiteral() const { return Str; }
-
- QualType getValueType() const override {
- return Str->getType();
- }
+ QualType getValueType() const override { return Str->getType(); }
DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
@@ -817,7 +829,7 @@ public:
class ObjCStringRegion : public TypedValueRegion {
friend class MemRegionManager;
- const ObjCStringLiteral* Str;
+ const ObjCStringLiteral *Str;
ObjCStringRegion(const ObjCStringLiteral *str,
const GlobalInternalSpaceRegion *sreg)
@@ -825,17 +837,14 @@ class ObjCStringRegion : public TypedValueRegion {
assert(str);
}
- static void ProfileRegion(llvm::FoldingSetNodeID& ID,
- const ObjCStringLiteral* Str,
- const MemRegion* superRegion);
+ static void ProfileRegion(llvm::FoldingSetNodeID &ID,
+ const ObjCStringLiteral *Str,
+ const MemRegion *superRegion);
public:
-
- const ObjCStringLiteral* getObjCStringLiteral() const { return Str; }
+ const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
- QualType getValueType() const override {
- return Str->getType();
- }
+ QualType getValueType() const override { return Str->getType(); }
bool isBoundable() const override { return false; }
@@ -869,10 +878,9 @@ class CompoundLiteralRegion : public TypedValueRegion {
static void ProfileRegion(llvm::FoldingSetNodeID& ID,
const CompoundLiteralExpr *CL,
const MemRegion* superRegion);
+
public:
- QualType getValueType() const override {
- return CL->getType();
- }
+ QualType getValueType() const override { return CL->getType(); }
bool isBoundable() const override { return !CL->isFileScope(); }
@@ -943,13 +951,13 @@ public:
void dumpToStream(raw_ostream &os) const override;
- static bool classof(const MemRegion* R) {
- return R->getKind() == VarRegionKind;
- }
-
bool canPrintPrettyAsExpr() const override;
void printPrettyAsExpr(raw_ostream &os) const override;
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == VarRegionKind;
+ }
};
/// CXXThisRegion - Represents the region for the implicit 'this' parameter
@@ -961,7 +969,10 @@ class CXXThisRegion : public TypedValueRegion {
CXXThisRegion(const PointerType *thisPointerTy,
const StackArgumentsSpaceRegion *sReg)
: TypedValueRegion(sReg, CXXThisRegionKind),
- ThisPointerTy(thisPointerTy) {}
+ ThisPointerTy(thisPointerTy) {
+ assert(ThisPointerTy->getPointeeType()->getAsCXXRecordDecl() &&
+ "Invalid region type!");
+ }
static void ProfileRegion(llvm::FoldingSetNodeID &ID,
const PointerType *PT,
@@ -988,7 +999,7 @@ class FieldRegion : public DeclRegion {
friend class MemRegionManager;
FieldRegion(const FieldDecl *fd, const SubRegion* sReg)
- : DeclRegion(fd, sReg, FieldRegionKind) {}
+ : DeclRegion(fd, sReg, FieldRegionKind) {}
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
const MemRegion* superRegion) {
@@ -1005,16 +1016,16 @@ public:
DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
- static bool classof(const MemRegion* R) {
- return R->getKind() == FieldRegionKind;
- }
-
void dumpToStream(raw_ostream &os) const override;
bool canPrintPretty() const override;
void printPretty(raw_ostream &os) const override;
bool canPrintPrettyAsExpr() const override;
void printPrettyAsExpr(raw_ostream &os) const override;
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == FieldRegionKind;
+ }
};
class ObjCIvarRegion : public DeclRegion {
@@ -1038,12 +1049,11 @@ public:
return R->getKind() == ObjCIvarRegionKind;
}
};
+
//===----------------------------------------------------------------------===//
// Auxiliary data classes for use with MemRegions.
//===----------------------------------------------------------------------===//
-class ElementRegion;
-
class RegionRawOffset {
friend class ElementRegion;
@@ -1051,7 +1061,7 @@ class RegionRawOffset {
CharUnits Offset;
RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
- : Region(reg), Offset(offset) {}
+ : Region(reg), Offset(offset) {}
public:
// FIXME: Eventually support symbolic offsets.
@@ -1062,7 +1072,7 @@ public:
void dump() const;
};
-/// \brief ElementRegin is used to represent both array elements and casts.
+/// ElementRegin is used to represent both array elements and casts.
class ElementRegion : public TypedValueRegion {
friend class MemRegionManager;
@@ -1070,27 +1080,25 @@ class ElementRegion : public TypedValueRegion {
NonLoc Index;
ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
- : TypedValueRegion(sReg, ElementRegionKind),
- ElementType(elementType), Index(Idx) {
+ : TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
+ Index(Idx) {
assert((!Idx.getAs<nonloc::ConcreteInt>() ||
Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
"The index must be signed");
+ assert(!elementType.isNull() && !elementType->isVoidType() &&
+ "Invalid region type!");
}
static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
SVal Idx, const MemRegion* superRegion);
public:
-
NonLoc getIndex() const { return Index; }
- QualType getValueType() const override {
- return ElementType;
- }
+ QualType getValueType() const override { return ElementType; }
+
+ QualType getElementType() const { return ElementType; }
- QualType getElementType() const {
- return ElementType;
- }
/// Compute the offset within the array. The array might also be a subobject.
RegionRawOffset getAsArrayOffset() const;
@@ -1122,9 +1130,7 @@ class CXXTempObjectRegion : public TypedValueRegion {
public:
const Expr *getExpr() const { return Ex; }
- QualType getValueType() const override {
- return Ex->getType();
- }
+ QualType getValueType() const override { return Ex->getType(); }
void dumpToStream(raw_ostream &os) const override;
@@ -1161,18 +1167,18 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const override;
- static bool classof(const MemRegion *region) {
- return region->getKind() == CXXBaseObjectRegionKind;
- }
-
bool canPrintPrettyAsExpr() const override;
void printPrettyAsExpr(raw_ostream &os) const override;
+
+ static bool classof(const MemRegion *region) {
+ return region->getKind() == CXXBaseObjectRegionKind;
+ }
};
template<typename RegionTy>
const RegionTy* MemRegion::getAs() const {
- if (const RegionTy* RT = dyn_cast<RegionTy>(this))
+ if (const auto *RT = dyn_cast<RegionTy>(this))
return RT;
return nullptr;
@@ -1187,11 +1193,10 @@ class MemRegionManager {
llvm::BumpPtrAllocator& A;
llvm::FoldingSet<MemRegion> Regions;
- GlobalInternalSpaceRegion *InternalGlobals;
- GlobalSystemSpaceRegion *SystemGlobals;
- GlobalImmutableSpaceRegion *ImmutableGlobals;
+ GlobalInternalSpaceRegion *InternalGlobals = nullptr;
+ GlobalSystemSpaceRegion *SystemGlobals = nullptr;
+ GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr;
-
llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
StackLocalsSpaceRegions;
llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
@@ -1199,16 +1204,12 @@ class MemRegionManager {
llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
StaticsGlobalSpaceRegions;
- HeapSpaceRegion *heap;
- UnknownSpaceRegion *unknown;
- CodeSpaceRegion *code;
+ HeapSpaceRegion *heap = nullptr;
+ UnknownSpaceRegion *unknown = nullptr;
+ CodeSpaceRegion *code = nullptr;
public:
- MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a)
- : C(c), A(a), InternalGlobals(nullptr), SystemGlobals(nullptr),
- ImmutableGlobals(nullptr), heap(nullptr), unknown(nullptr),
- code(nullptr) {}
-
+ MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : C(c), A(a) {}
~MemRegionManager();
ASTContext &getContext() { return C; }
@@ -1256,13 +1257,13 @@ public:
const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
const LocationContext *LC);
- /// \brief Retrieve or create a "symbolic" memory region.
+ /// Retrieve or create a "symbolic" memory region.
const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
- /// \brief Return a unique symbolic region belonging to heap memory space.
+ /// Return a unique symbolic region belonging to heap memory space.
const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
- const StringRegion *getStringRegion(const StringLiteral* Str);
+ const StringRegion *getStringRegion(const StringLiteral *Str);
const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
@@ -1381,24 +1382,28 @@ inline ASTContext &MemRegion::getContext() const {
/// Information about invalidation for a particular region/symbol.
class RegionAndSymbolInvalidationTraits {
- typedef unsigned char StorageTypeForKinds;
+ using StorageTypeForKinds = unsigned char;
+
llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
- typedef llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator
- const_region_iterator;
- typedef llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator
- const_symbol_iterator;
+ using const_region_iterator =
+ llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator;
+ using const_symbol_iterator =
+ llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator;
public:
- /// \brief Describes different invalidation traits.
+ /// Describes different invalidation traits.
enum InvalidationKinds {
/// Tells that a region's contents is not changed.
TK_PreserveContents = 0x1,
+
/// Suppress pointer-escaping of a region.
TK_SuppressEscape = 0x2,
+
// Do not invalidate super region.
TK_DoNotInvalidateSuperRegion = 0x4,
+
/// When applied to a MemSpaceRegion, indicates the entire memory space
/// should be invalidated.
TK_EntireMemSpace = 0x8
@@ -1416,8 +1421,7 @@ public:
//===----------------------------------------------------------------------===//
// Pretty-printing regions.
//===----------------------------------------------------------------------===//
-inline raw_ostream &operator<<(raw_ostream &os,
- const clang::ento::MemRegion *R) {
+inline raw_ostream &operator<<(raw_ostream &os, const MemRegion *R) {
R->dumpToStream(os);
return os;
}
@@ -1426,4 +1430,4 @@ inline raw_ostream &operator<<(raw_ostream &os,
} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_MEMREGION_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index dd2564b0a3c3e..17ab7379fdba9 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -177,20 +177,20 @@ public:
///
/// This returns a new state with the added constraint on \p cond.
/// If no new state is feasible, NULL is returned.
- ProgramStateRef assume(DefinedOrUnknownSVal cond, bool assumption) const;
+ LLVM_NODISCARD ProgramStateRef assume(DefinedOrUnknownSVal cond,
+ bool assumption) const;
/// Assumes both "true" and "false" for \p cond, and returns both
/// corresponding states (respectively).
///
/// This is more efficient than calling assume() twice. Note that one (but not
/// both) of the returned states may be NULL.
- std::pair<ProgramStateRef, ProgramStateRef>
+ LLVM_NODISCARD std::pair<ProgramStateRef, ProgramStateRef>
assume(DefinedOrUnknownSVal cond) const;
- ProgramStateRef assumeInBound(DefinedOrUnknownSVal idx,
- DefinedOrUnknownSVal upperBound,
- bool assumption,
- QualType IndexType = QualType()) const;
+ LLVM_NODISCARD ProgramStateRef
+ assumeInBound(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound,
+ bool assumption, QualType IndexType = QualType()) const;
/// Assumes that the value of \p Val is bounded with [\p From; \p To]
/// (if \p assumption is "true") or it is fully out of this range
@@ -198,24 +198,31 @@ public:
///
/// This returns a new state with the added constraint on \p cond.
/// If no new state is feasible, NULL is returned.
- ProgramStateRef assumeInclusiveRange(DefinedOrUnknownSVal Val,
- const llvm::APSInt &From,
- const llvm::APSInt &To,
- bool assumption) const;
+ LLVM_NODISCARD ProgramStateRef assumeInclusiveRange(DefinedOrUnknownSVal Val,
+ const llvm::APSInt &From,
+ const llvm::APSInt &To,
+ bool assumption) const;
/// Assumes given range both "true" and "false" for \p Val, and returns both
/// corresponding states (respectively).
///
/// This is more efficient than calling assume() twice. Note that one (but not
/// both) of the returned states may be NULL.
- std::pair<ProgramStateRef, ProgramStateRef>
+ LLVM_NODISCARD std::pair<ProgramStateRef, ProgramStateRef>
assumeInclusiveRange(DefinedOrUnknownSVal Val, const llvm::APSInt &From,
const llvm::APSInt &To) const;
- /// \brief Check if the given SVal is constrained to zero or is a zero
+ /// Check if the given SVal is not constrained to zero and is not
+ /// a zero constant.
+ ConditionTruthVal isNonNull(SVal V) const;
+
+ /// Check if the given SVal is constrained to zero or is a zero
/// constant.
ConditionTruthVal isNull(SVal V) const;
+ /// \return Whether values \p Lhs and \p Rhs are equal.
+ ConditionTruthVal areEqual(SVal Lhs, SVal Rhs) const;
+
/// Utility method for getting regions.
const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
@@ -225,21 +232,34 @@ public:
/// Create a new state by binding the value 'V' to the statement 'S' in the
/// state's environment.
- ProgramStateRef BindExpr(const Stmt *S, const LocationContext *LCtx,
- SVal V, bool Invalidate = true) const;
-
- ProgramStateRef bindLoc(Loc location,
- SVal V,
- const LocationContext *LCtx,
- bool notifyChanges = true) const;
-
- ProgramStateRef bindLoc(SVal location, SVal V, const LocationContext *LCtx) const;
-
- ProgramStateRef bindDefault(SVal loc, SVal V, const LocationContext *LCtx) const;
-
- ProgramStateRef killBinding(Loc LV) const;
-
- /// \brief Returns the state with bindings for the given regions
+ LLVM_NODISCARD ProgramStateRef BindExpr(const Stmt *S,
+ const LocationContext *LCtx, SVal V,
+ bool Invalidate = true) const;
+
+ LLVM_NODISCARD ProgramStateRef bindLoc(Loc location, SVal V,
+ const LocationContext *LCtx,
+ bool notifyChanges = true) const;
+
+ LLVM_NODISCARD ProgramStateRef bindLoc(SVal location, SVal V,
+ const LocationContext *LCtx) const;
+
+ /// Initializes the region of memory represented by \p loc with an initial
+ /// value. Once initialized, all values loaded from any sub-regions of that
+ /// region will be equal to \p V, unless overwritten later by the program.
+ /// This method should not be used on regions that are already initialized.
+ /// If you need to indicate that memory contents have suddenly become unknown
+ /// within a certain region of memory, consider invalidateRegions().
+ LLVM_NODISCARD ProgramStateRef
+ bindDefaultInitial(SVal loc, SVal V, const LocationContext *LCtx) const;
+
+ /// Performs C++ zero-initialization procedure on the region of memory
+ /// represented by \p loc.
+ LLVM_NODISCARD ProgramStateRef
+ bindDefaultZero(SVal loc, const LocationContext *LCtx) const;
+
+ LLVM_NODISCARD ProgramStateRef killBinding(Loc LV) const;
+
+ /// Returns the state with bindings for the given regions
/// cleared from the store.
///
/// Optionally invalidates global regions as well.
@@ -257,14 +277,14 @@ public:
/// the call and should be considered directly invalidated.
/// \param ITraits information about special handling for a particular
/// region/symbol.
- ProgramStateRef
+ LLVM_NODISCARD ProgramStateRef
invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E,
unsigned BlockCount, const LocationContext *LCtx,
bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr,
const CallEvent *Call = nullptr,
RegionAndSymbolInvalidationTraits *ITraits = nullptr) const;
- ProgramStateRef
+ LLVM_NODISCARD ProgramStateRef
invalidateRegions(ArrayRef<SVal> Regions, const Expr *E,
unsigned BlockCount, const LocationContext *LCtx,
bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr,
@@ -273,8 +293,15 @@ public:
/// enterStackFrame - Returns the state for entry to the given stack frame,
/// preserving the current state.
- ProgramStateRef enterStackFrame(const CallEvent &Call,
- const StackFrameContext *CalleeCtx) const;
+ LLVM_NODISCARD ProgramStateRef enterStackFrame(
+ const CallEvent &Call, const StackFrameContext *CalleeCtx) const;
+
+ /// Get the lvalue for a base class object reference.
+ Loc getLValue(const CXXBaseSpecifier &BaseSpec, const SubRegion *Super) const;
+
+ /// Get the lvalue for a base class object reference.
+ Loc getLValue(const CXXRecordDecl *BaseClass, const SubRegion *Super,
+ bool IsVirtual) const;
/// Get the lvalue for a variable reference.
Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
@@ -299,24 +326,24 @@ public:
SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const;
- /// \brief Return the value bound to the specified location.
+ /// Return the value bound to the specified location.
/// Returns UnknownVal() if none found.
SVal getSVal(Loc LV, QualType T = QualType()) const;
/// Returns the "raw" SVal bound to LV before any value simplfication.
SVal getRawSVal(Loc LV, QualType T= QualType()) const;
- /// \brief Return the value bound to the specified location.
+ /// Return the value bound to the specified location.
/// Returns UnknownVal() if none found.
SVal getSVal(const MemRegion* R, QualType T = QualType()) const;
- /// \brief Return the value bound to the specified location, assuming
+ /// Return the value bound to the specified location, assuming
/// that the value is a scalar integer or an enumeration or a pointer.
/// Returns UnknownVal() if none found or the region is not known to hold
/// a value of such type.
SVal getSValAsScalarOrLoc(const MemRegion *R) const;
- /// \brief Visits the symbols reachable from the given SVal using the provided
+ /// Visits the symbols reachable from the given SVal using the provided
/// SymbolVisitor.
///
/// This is a convenience API. Consider using ScanReachableSymbols class
@@ -325,12 +352,12 @@ public:
/// \sa ScanReachableSymbols
bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
- /// \brief Visits the symbols reachable from the SVals in the given range
+ /// Visits the symbols reachable from the SVals in the given range
/// using the provided SymbolVisitor.
bool scanReachableSymbols(const SVal *I, const SVal *E,
SymbolVisitor &visitor) const;
- /// \brief Visits the symbols reachable from the regions in the given
+ /// Visits the symbols reachable from the regions in the given
/// MemRegions range using the provided SymbolVisitor.
bool scanReachableSymbols(const MemRegion * const *I,
const MemRegion * const *E,
@@ -345,27 +372,29 @@ public:
const MemRegion * const *end) const;
/// Create a new state in which the statement is marked as tainted.
- ProgramStateRef addTaint(const Stmt *S, const LocationContext *LCtx,
- TaintTagType Kind = TaintTagGeneric) const;
+ LLVM_NODISCARD ProgramStateRef
+ addTaint(const Stmt *S, const LocationContext *LCtx,
+ TaintTagType Kind = TaintTagGeneric) const;
/// Create a new state in which the value is marked as tainted.
- ProgramStateRef addTaint(SVal V, TaintTagType Kind = TaintTagGeneric) const;
+ LLVM_NODISCARD ProgramStateRef
+ addTaint(SVal V, TaintTagType Kind = TaintTagGeneric) const;
/// Create a new state in which the symbol is marked as tainted.
- ProgramStateRef addTaint(SymbolRef S,
+ LLVM_NODISCARD ProgramStateRef addTaint(SymbolRef S,
TaintTagType Kind = TaintTagGeneric) const;
/// Create a new state in which the region symbol is marked as tainted.
- ProgramStateRef addTaint(const MemRegion *R,
- TaintTagType Kind = TaintTagGeneric) const;
+ LLVM_NODISCARD ProgramStateRef
+ addTaint(const MemRegion *R, TaintTagType Kind = TaintTagGeneric) const;
/// Create a new state in a which a sub-region of a given symbol is tainted.
/// This might be necessary when referring to regions that can not have an
/// individual symbol, e.g. if they are represented by the default binding of
/// a LazyCompoundVal.
- ProgramStateRef addPartialTaint(SymbolRef ParentSym,
- const SubRegion *SubRegion,
- TaintTagType Kind = TaintTagGeneric) const;
+ LLVM_NODISCARD ProgramStateRef
+ addPartialTaint(SymbolRef ParentSym, const SubRegion *SubRegion,
+ TaintTagType Kind = TaintTagGeneric) const;
/// Check if the statement is tainted in the current state.
bool isTainted(const Stmt *S, const LocationContext *LCtx,
@@ -380,8 +409,9 @@ public:
void *const* FindGDM(void *K) const;
- template<typename T>
- ProgramStateRef add(typename ProgramStateTrait<T>::key_type K) const;
+ template <typename T>
+ LLVM_NODISCARD ProgramStateRef
+ add(typename ProgramStateTrait<T>::key_type K) const;
template <typename T>
typename ProgramStateTrait<T>::data_type
@@ -399,27 +429,31 @@ public:
template <typename T>
typename ProgramStateTrait<T>::context_type get_context() const;
+ template <typename T>
+ LLVM_NODISCARD ProgramStateRef
+ remove(typename ProgramStateTrait<T>::key_type K) const;
- template<typename T>
- ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K) const;
-
- template<typename T>
- ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K,
- typename ProgramStateTrait<T>::context_type C) const;
template <typename T>
- ProgramStateRef remove() const;
+ LLVM_NODISCARD ProgramStateRef
+ remove(typename ProgramStateTrait<T>::key_type K,
+ typename ProgramStateTrait<T>::context_type C) const;
- template<typename T>
- ProgramStateRef set(typename ProgramStateTrait<T>::data_type D) const;
+ template <typename T> LLVM_NODISCARD ProgramStateRef remove() const;
- template<typename T>
- ProgramStateRef set(typename ProgramStateTrait<T>::key_type K,
- typename ProgramStateTrait<T>::value_type E) const;
+ template <typename T>
+ LLVM_NODISCARD ProgramStateRef
+ set(typename ProgramStateTrait<T>::data_type D) const;
- template<typename T>
- ProgramStateRef set(typename ProgramStateTrait<T>::key_type K,
- typename ProgramStateTrait<T>::value_type E,
- typename ProgramStateTrait<T>::context_type C) const;
+ template <typename T>
+ LLVM_NODISCARD ProgramStateRef
+ set(typename ProgramStateTrait<T>::key_type K,
+ typename ProgramStateTrait<T>::value_type E) const;
+
+ template <typename T>
+ LLVM_NODISCARD ProgramStateRef
+ set(typename ProgramStateTrait<T>::key_type K,
+ typename ProgramStateTrait<T>::value_type E,
+ typename ProgramStateTrait<T>::context_type C) const;
template<typename T>
bool contains(typename ProgramStateTrait<T>::key_type key) const {
@@ -428,9 +462,10 @@ public:
}
// Pretty-printing.
- void print(raw_ostream &Out, const char *nl = "\n",
- const char *sep = "") const;
- void printDOT(raw_ostream &Out) const;
+ void print(raw_ostream &Out, const char *nl = "\n", const char *sep = "",
+ const LocationContext *CurrentLC = nullptr) const;
+ void printDOT(raw_ostream &Out,
+ const LocationContext *CurrentLC = nullptr) const;
void printTaint(raw_ostream &Out, const char *nl = "\n",
const char *sep = "") const;
@@ -705,6 +740,22 @@ inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V, const LocationCont
return this;
}
+inline Loc ProgramState::getLValue(const CXXBaseSpecifier &BaseSpec,
+ const SubRegion *Super) const {
+ const auto *Base = BaseSpec.getType()->getAsCXXRecordDecl();
+ return loc::MemRegionVal(
+ getStateManager().getRegionManager().getCXXBaseObjectRegion(
+ Base, Super, BaseSpec.isVirtual()));
+}
+
+inline Loc ProgramState::getLValue(const CXXRecordDecl *BaseClass,
+ const SubRegion *Super,
+ bool IsVirtual) const {
+ return loc::MemRegionVal(
+ getStateManager().getRegionManager().getCXXBaseObjectRegion(
+ BaseClass, Super, IsVirtual));
+}
+
inline Loc ProgramState::getLValue(const VarDecl *VD,
const LocationContext *LC) const {
return getStateManager().StoreMgr->getLValueVar(VD, LC);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
index a04fa90059555..5555b292534c5 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
@@ -14,33 +14,28 @@
//
//===----------------------------------------------------------------------===//
-
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATETRAIT_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATETRAIT_H
+#include "llvm/ADT/ImmutableList.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/ImmutableSet.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/DataTypes.h"
-
-namespace llvm {
- template <typename K, typename D, typename I> class ImmutableMap;
- template <typename K, typename I> class ImmutableSet;
- template <typename T> class ImmutableList;
- template <typename T> class ImmutableListImpl;
-}
+#include <cstdint>
namespace clang {
-
namespace ento {
+
template <typename T> struct ProgramStatePartialTrait;
/// Declares a program state trait for type \p Type called \p Name, and
- /// introduce a typedef named \c NameTy.
+ /// introduce a type named \c NameTy.
/// The macro should not be used inside namespaces, or for traits that must
/// be accessible from more than one translation unit.
#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type) \
namespace { \
class Name {}; \
- typedef Type Name ## Ty; \
+ using Name ## Ty = Type; \
} \
namespace clang { \
namespace ento { \
@@ -52,28 +47,30 @@ namespace ento {
} \
}
-
// Partial-specialization for ImmutableMap.
-
template <typename Key, typename Data, typename Info>
- struct ProgramStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > {
- typedef llvm::ImmutableMap<Key,Data,Info> data_type;
- typedef typename data_type::Factory& context_type;
- typedef Key key_type;
- typedef Data value_type;
- typedef const value_type* lookup_type;
-
- static inline data_type MakeData(void *const* p) {
- return p ? data_type((typename data_type::TreeTy*) *p)
+ struct ProgramStatePartialTrait<llvm::ImmutableMap<Key, Data, Info>> {
+ using data_type = llvm::ImmutableMap<Key, Data, Info>;
+ using context_type = typename data_type::Factory &;
+ using key_type = Key;
+ using value_type = Data;
+ using lookup_type = const value_type *;
+
+ static data_type MakeData(void *const *p) {
+ return p ? data_type((typename data_type::TreeTy *) *p)
: data_type(nullptr);
}
- static inline void *MakeVoidPtr(data_type B) {
+
+ static void *MakeVoidPtr(data_type B) {
return B.getRoot();
}
+
static lookup_type Lookup(data_type B, key_type K) {
return B.lookup(K);
}
- static data_type Set(data_type B, key_type K, value_type E,context_type F){
+
+ static data_type Set(data_type B, key_type K, value_type E,
+ context_type F) {
return F.add(B, K, E);
}
@@ -85,8 +82,8 @@ namespace ento {
return B.contains(K);
}
- static inline context_type MakeContext(void *p) {
- return *((typename data_type::Factory*) p);
+ static context_type MakeContext(void *p) {
+ return *((typename data_type::Factory *) p);
}
static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
@@ -94,7 +91,7 @@ namespace ento {
}
static void DeleteContext(void *Ctx) {
- delete (typename data_type::Factory*) Ctx;
+ delete (typename data_type::Factory *) Ctx;
}
};
@@ -107,21 +104,19 @@ namespace ento {
/// can deal with.
#define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap<Key, Value>
-
// Partial-specialization for ImmutableSet.
-
template <typename Key, typename Info>
- struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > {
- typedef llvm::ImmutableSet<Key,Info> data_type;
- typedef typename data_type::Factory& context_type;
- typedef Key key_type;
+ struct ProgramStatePartialTrait<llvm::ImmutableSet<Key, Info>> {
+ using data_type = llvm::ImmutableSet<Key, Info>;
+ using context_type = typename data_type::Factory &;
+ using key_type = Key;
- static inline data_type MakeData(void *const* p) {
- return p ? data_type((typename data_type::TreeTy*) *p)
+ static data_type MakeData(void *const *p) {
+ return p ? data_type((typename data_type::TreeTy *) *p)
: data_type(nullptr);
}
- static inline void *MakeVoidPtr(data_type B) {
+ static void *MakeVoidPtr(data_type B) {
return B.getRoot();
}
@@ -137,27 +132,25 @@ namespace ento {
return B.contains(K);
}
- static inline context_type MakeContext(void *p) {
- return *((typename data_type::Factory*) p);
+ static context_type MakeContext(void *p) {
+ return *((typename data_type::Factory *) p);
}
- static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
+ static void *CreateContext(llvm::BumpPtrAllocator &Alloc) {
return new typename data_type::Factory(Alloc);
}
static void DeleteContext(void *Ctx) {
- delete (typename data_type::Factory*) Ctx;
+ delete (typename data_type::Factory *) Ctx;
}
};
-
// Partial-specialization for ImmutableList.
-
template <typename T>
- struct ProgramStatePartialTrait< llvm::ImmutableList<T> > {
- typedef llvm::ImmutableList<T> data_type;
- typedef T key_type;
- typedef typename data_type::Factory& context_type;
+ struct ProgramStatePartialTrait<llvm::ImmutableList<T>> {
+ using data_type = llvm::ImmutableList<T>;
+ using key_type = T;
+ using context_type = typename data_type::Factory &;
static data_type Add(data_type L, key_type K, context_type F) {
return F.add(K, L);
@@ -167,83 +160,84 @@ namespace ento {
return L.contains(K);
}
- static inline data_type MakeData(void *const* p) {
- return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
+ static data_type MakeData(void *const *p) {
+ return p ? data_type((const llvm::ImmutableListImpl<T> *) *p)
: data_type(nullptr);
}
- static inline void *MakeVoidPtr(data_type D) {
+ static void *MakeVoidPtr(data_type D) {
return const_cast<llvm::ImmutableListImpl<T> *>(D.getInternalPointer());
}
- static inline context_type MakeContext(void *p) {
- return *((typename data_type::Factory*) p);
+ static context_type MakeContext(void *p) {
+ return *((typename data_type::Factory *) p);
}
- static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
+ static void *CreateContext(llvm::BumpPtrAllocator &Alloc) {
return new typename data_type::Factory(Alloc);
}
static void DeleteContext(void *Ctx) {
- delete (typename data_type::Factory*) Ctx;
+ delete (typename data_type::Factory *) Ctx;
}
};
-
// Partial specialization for bool.
template <> struct ProgramStatePartialTrait<bool> {
- typedef bool data_type;
+ using data_type = bool;
- static inline data_type MakeData(void *const* p) {
+ static data_type MakeData(void *const *p) {
return p ? (data_type) (uintptr_t) *p
: data_type();
}
- static inline void *MakeVoidPtr(data_type d) {
- return (void*) (uintptr_t) d;
+
+ static void *MakeVoidPtr(data_type d) {
+ return (void *) (uintptr_t) d;
}
};
// Partial specialization for unsigned.
template <> struct ProgramStatePartialTrait<unsigned> {
- typedef unsigned data_type;
+ using data_type = unsigned;
- static inline data_type MakeData(void *const* p) {
+ static data_type MakeData(void *const *p) {
return p ? (data_type) (uintptr_t) *p
: data_type();
}
- static inline void *MakeVoidPtr(data_type d) {
- return (void*) (uintptr_t) d;
+
+ static void *MakeVoidPtr(data_type d) {
+ return (void *) (uintptr_t) d;
}
};
// Partial specialization for void*.
- template <> struct ProgramStatePartialTrait<void*> {
- typedef void *data_type;
+ template <> struct ProgramStatePartialTrait<void *> {
+ using data_type = void *;
- static inline data_type MakeData(void *const* p) {
+ static data_type MakeData(void *const *p) {
return p ? *p
: data_type();
}
- static inline void *MakeVoidPtr(data_type d) {
+
+ static void *MakeVoidPtr(data_type d) {
return d;
}
};
// Partial specialization for const void *.
template <> struct ProgramStatePartialTrait<const void *> {
- typedef const void *data_type;
+ using data_type = const void *;
- static inline data_type MakeData(void * const *p) {
+ static data_type MakeData(void *const *p) {
return p ? *p : data_type();
}
- static inline void *MakeVoidPtr(data_type d) {
+ static void *MakeVoidPtr(data_type d) {
return const_cast<void *>(d);
}
};
-} // end ento namespace
-
-} // end clang namespace
+} // namespace ento
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATETRAIT_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h
new file mode 100644
index 0000000000000..d2ba1f7c9529a
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h
@@ -0,0 +1,216 @@
+//== RangedConstraintManager.h ----------------------------------*- C++ -*--==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Ranged constraint manager, built on SimpleConstraintManager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CORE_RANGEDCONSTRAINTMANAGER_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CORE_RANGEDCONSTRAINTMANAGER_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h"
+
+namespace clang {
+
+namespace ento {
+
+/// A Range represents the closed range [from, to]. The caller must
+/// guarantee that from <= to. Note that Range is immutable, so as not
+/// to subvert RangeSet's immutability.
+class Range : public std::pair<const llvm::APSInt *, const llvm::APSInt *> {
+public:
+ Range(const llvm::APSInt &from, const llvm::APSInt &to)
+ : std::pair<const llvm::APSInt *, const llvm::APSInt *>(&from, &to) {
+ assert(from <= to);
+ }
+ bool Includes(const llvm::APSInt &v) const {
+ return *first <= v && v <= *second;
+ }
+ const llvm::APSInt &From() const { return *first; }
+ const llvm::APSInt &To() const { return *second; }
+ const llvm::APSInt *getConcreteValue() const {
+ return &From() == &To() ? &From() : nullptr;
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddPointer(&From());
+ ID.AddPointer(&To());
+ }
+};
+
+class RangeTrait : public llvm::ImutContainerInfo<Range> {
+public:
+ // When comparing if one Range is less than another, we should compare
+ // the actual APSInt values instead of their pointers. This keeps the order
+ // consistent (instead of comparing by pointer values) and can potentially
+ // be used to speed up some of the operations in RangeSet.
+ static inline bool isLess(key_type_ref lhs, key_type_ref rhs) {
+ return *lhs.first < *rhs.first ||
+ (!(*rhs.first < *lhs.first) && *lhs.second < *rhs.second);
+ }
+};
+
+/// RangeSet contains a set of ranges. If the set is empty, then
+/// there the value of a symbol is overly constrained and there are no
+/// possible values for that symbol.
+class RangeSet {
+ typedef llvm::ImmutableSet<Range, RangeTrait> PrimRangeSet;
+ PrimRangeSet ranges; // no need to make const, since it is an
+ // ImmutableSet - this allows default operator=
+ // to work.
+public:
+ typedef PrimRangeSet::Factory Factory;
+ typedef PrimRangeSet::iterator iterator;
+
+ RangeSet(PrimRangeSet RS) : ranges(RS) {}
+
+ /// Create a new set with all ranges of this set and RS.
+ /// Possible intersections are not checked here.
+ RangeSet addRange(Factory &F, const RangeSet &RS) {
+ PrimRangeSet Ranges(RS.ranges);
+ for (const auto &range : ranges)
+ Ranges = F.add(Ranges, range);
+ return RangeSet(Ranges);
+ }
+
+ iterator begin() const { return ranges.begin(); }
+ iterator end() const { return ranges.end(); }
+
+ bool isEmpty() const { return ranges.isEmpty(); }
+
+ /// Construct a new RangeSet representing '{ [from, to] }'.
+ RangeSet(Factory &F, const llvm::APSInt &from, const llvm::APSInt &to)
+ : ranges(F.add(F.getEmptySet(), Range(from, to))) {}
+
+ /// Profile - Generates a hash profile of this RangeSet for use
+ /// by FoldingSet.
+ void Profile(llvm::FoldingSetNodeID &ID) const { ranges.Profile(ID); }
+
+ /// getConcreteValue - If a symbol is contrained to equal a specific integer
+ /// constant then this method returns that value. Otherwise, it returns
+ /// NULL.
+ const llvm::APSInt *getConcreteValue() const {
+ return ranges.isSingleton() ? ranges.begin()->getConcreteValue() : nullptr;
+ }
+
+private:
+ void IntersectInRange(BasicValueFactory &BV, Factory &F,
+ const llvm::APSInt &Lower, const llvm::APSInt &Upper,
+ PrimRangeSet &newRanges, PrimRangeSet::iterator &i,
+ PrimRangeSet::iterator &e) const;
+
+ const llvm::APSInt &getMinValue() const;
+
+ bool pin(llvm::APSInt &Lower, llvm::APSInt &Upper) const;
+
+public:
+ RangeSet Intersect(BasicValueFactory &BV, Factory &F, llvm::APSInt Lower,
+ llvm::APSInt Upper) const;
+
+ RangeSet Negate(BasicValueFactory &BV, Factory &F) const;
+
+ void print(raw_ostream &os) const;
+
+ bool operator==(const RangeSet &other) const {
+ return ranges == other.ranges;
+ }
+};
+
+
+class ConstraintRange {};
+using ConstraintRangeTy = llvm::ImmutableMap<SymbolRef, RangeSet>;
+
+template <>
+struct ProgramStateTrait<ConstraintRange>
+ : public ProgramStatePartialTrait<ConstraintRangeTy> {
+ static void *GDMIndex() { static int Index; return &Index; }
+};
+
+
+class RangedConstraintManager : public SimpleConstraintManager {
+public:
+ RangedConstraintManager(SubEngine *SE, SValBuilder &SB)
+ : SimpleConstraintManager(SE, SB) {}
+
+ ~RangedConstraintManager() override;
+
+ //===------------------------------------------------------------------===//
+ // Implementation for interface from SimpleConstraintManager.
+ //===------------------------------------------------------------------===//
+
+ ProgramStateRef assumeSym(ProgramStateRef State, SymbolRef Sym,
+ bool Assumption) override;
+
+ ProgramStateRef assumeSymInclusiveRange(ProgramStateRef State, SymbolRef Sym,
+ const llvm::APSInt &From,
+ const llvm::APSInt &To,
+ bool InRange) override;
+
+ ProgramStateRef assumeSymUnsupported(ProgramStateRef State, SymbolRef Sym,
+ bool Assumption) override;
+
+protected:
+ /// Assume a constraint between a symbolic expression and a concrete integer.
+ virtual ProgramStateRef assumeSymRel(ProgramStateRef State, SymbolRef Sym,
+ BinaryOperator::Opcode op,
+ const llvm::APSInt &Int);
+
+ //===------------------------------------------------------------------===//
+ // Interface that subclasses must implement.
+ //===------------------------------------------------------------------===//
+
+ // Each of these is of the form "$Sym+Adj <> V", where "<>" is the comparison
+ // operation for the method being invoked.
+
+ virtual ProgramStateRef assumeSymNE(ProgramStateRef State, SymbolRef Sym,
+ const llvm::APSInt &V,
+ const llvm::APSInt &Adjustment) = 0;
+
+ virtual ProgramStateRef assumeSymEQ(ProgramStateRef State, SymbolRef Sym,
+ const llvm::APSInt &V,
+ const llvm::APSInt &Adjustment) = 0;
+
+ virtual ProgramStateRef assumeSymLT(ProgramStateRef State, SymbolRef Sym,
+ const llvm::APSInt &V,
+ const llvm::APSInt &Adjustment) = 0;
+
+ virtual ProgramStateRef assumeSymGT(ProgramStateRef State, SymbolRef Sym,
+ const llvm::APSInt &V,
+ const llvm::APSInt &Adjustment) = 0;
+
+ virtual ProgramStateRef assumeSymLE(ProgramStateRef State, SymbolRef Sym,
+ const llvm::APSInt &V,
+ const llvm::APSInt &Adjustment) = 0;
+
+ virtual ProgramStateRef assumeSymGE(ProgramStateRef State, SymbolRef Sym,
+ const llvm::APSInt &V,
+ const llvm::APSInt &Adjustment) = 0;
+
+ virtual ProgramStateRef assumeSymWithinInclusiveRange(
+ ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
+ const llvm::APSInt &To, const llvm::APSInt &Adjustment) = 0;
+
+ virtual ProgramStateRef assumeSymOutsideInclusiveRange(
+ ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
+ const llvm::APSInt &To, const llvm::APSInt &Adjustment) = 0;
+
+ //===------------------------------------------------------------------===//
+ // Internal implementation.
+ //===------------------------------------------------------------------===//
+private:
+ static void computeAdjustment(SymbolRef &Sym, llvm::APSInt &Adjustment);
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
new file mode 100644
index 0000000000000..19d3d5973e0fd
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
@@ -0,0 +1,77 @@
+//== SMTConstraintManager.h -------------------------------------*- 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 a SMT generic API, which will be the base class for
+// every SMT solver specific class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONSTRAINTMANAGER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONSTRAINTMANAGER_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h"
+
+namespace clang {
+namespace ento {
+
+class SMTConstraintManager : public clang::ento::SimpleConstraintManager {
+ SMTSolverRef &Solver;
+
+public:
+ SMTConstraintManager(clang::ento::SubEngine *SE, clang::ento::SValBuilder &SB,
+ SMTSolverRef &S)
+ : SimpleConstraintManager(SE, SB), Solver(S) {}
+ virtual ~SMTConstraintManager() = default;
+
+ //===------------------------------------------------------------------===//
+ // Implementation for interface from SimpleConstraintManager.
+ //===------------------------------------------------------------------===//
+
+ ProgramStateRef assumeSym(ProgramStateRef state, SymbolRef Sym,
+ bool Assumption) override;
+
+ ProgramStateRef assumeSymInclusiveRange(ProgramStateRef State, SymbolRef Sym,
+ const llvm::APSInt &From,
+ const llvm::APSInt &To,
+ bool InRange) override;
+
+ ProgramStateRef assumeSymUnsupported(ProgramStateRef State, SymbolRef Sym,
+ bool Assumption) override;
+
+ //===------------------------------------------------------------------===//
+ // Implementation for interface from ConstraintManager.
+ //===------------------------------------------------------------------===//
+
+ ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;
+
+ const llvm::APSInt *getSymVal(ProgramStateRef State,
+ SymbolRef Sym) const override;
+
+ /// Dumps SMT formula
+ LLVM_DUMP_METHOD void dump() const { Solver->dump(); }
+
+protected:
+ // Check whether a new model is satisfiable, and update the program state.
+ virtual ProgramStateRef assumeExpr(ProgramStateRef State, SymbolRef Sym,
+ const SMTExprRef &Exp) = 0;
+
+ /// Given a program state, construct the logical conjunction and add it to
+ /// the solver
+ virtual void addStateConstraints(ProgramStateRef State) const = 0;
+
+ // Generate and check a Z3 model, using the given constraint.
+ ConditionTruthVal checkModel(ProgramStateRef State,
+ const SMTExprRef &Exp) const;
+}; // end class SMTConstraintManager
+
+} // namespace ento
+} // namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTContext.h
new file mode 100644
index 0000000000000..45c9df4ef4019
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTContext.h
@@ -0,0 +1,31 @@
+//== SMTContext.h -----------------------------------------------*- 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 a SMT generic Context API, which will be the base class
+// for every SMT solver context specific class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONTEXT_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONTEXT_H
+
+namespace clang {
+namespace ento {
+
+/// Generic base class for SMT contexts
+class SMTContext {
+public:
+ SMTContext() = default;
+ virtual ~SMTContext() = default;
+};
+
+} // namespace ento
+} // namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h
new file mode 100644
index 0000000000000..9dedf96cfaf83
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h
@@ -0,0 +1,62 @@
+//== SMTExpr.h --------------------------------------------------*- 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 a SMT generic Expr API, which will be the base class
+// for every SMT solver expr specific class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTEXPR_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTEXPR_H
+
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/FoldingSet.h"
+
+namespace clang {
+namespace ento {
+
+/// Generic base class for SMT exprs
+class SMTExpr {
+public:
+ SMTExpr() = default;
+ virtual ~SMTExpr() = default;
+
+ bool operator<(const SMTExpr &Other) const {
+ llvm::FoldingSetNodeID ID1, ID2;
+ Profile(ID1);
+ Other.Profile(ID2);
+ return ID1 < ID2;
+ }
+
+ virtual void Profile(llvm::FoldingSetNodeID &ID) const {
+ static int Tag = 0;
+ ID.AddPointer(&Tag);
+ }
+
+ friend bool operator==(SMTExpr const &LHS, SMTExpr const &RHS) {
+ return LHS.equal_to(RHS);
+ }
+
+ virtual void print(raw_ostream &OS) const = 0;
+
+ LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); }
+
+protected:
+ /// Query the SMT solver and returns true if two sorts are equal (same kind
+ /// and bit width). This does not check if the two sorts are the same objects.
+ virtual bool equal_to(SMTExpr const &other) const = 0;
+};
+
+/// Shared pointer for SMTExprs, used by SMTSolver API.
+using SMTExprRef = std::shared_ptr<SMTExpr>;
+
+} // namespace ento
+} // namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h
new file mode 100644
index 0000000000000..a43ca486901bc
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h
@@ -0,0 +1,996 @@
+//== SMTSolver.h ------------------------------------------------*- 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 a SMT generic Solver API, which will be the base class
+// for every SMT solver specific class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSOLVER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSOLVER_H
+
+#include "clang/AST/Expr.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+
+namespace clang {
+namespace ento {
+
+/// Generic base class for SMT Solvers
+///
+/// This class is responsible for wrapping all sorts and expression generation,
+/// through the mk* methods. It also provides methods to create SMT expressions
+/// straight from clang's AST, through the from* methods.
+class SMTSolver {
+public:
+ SMTSolver() = default;
+ virtual ~SMTSolver() = default;
+
+ LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); }
+
+ // Returns an appropriate floating-point sort for the given bitwidth.
+ SMTSortRef getFloatSort(unsigned BitWidth) {
+ switch (BitWidth) {
+ case 16:
+ return getFloat16Sort();
+ case 32:
+ return getFloat32Sort();
+ case 64:
+ return getFloat64Sort();
+ case 128:
+ return getFloat128Sort();
+ default:;
+ }
+ llvm_unreachable("Unsupported floating-point bitwidth!");
+ }
+
+ // Returns an appropriate sort, given a QualType and it's bit width.
+ SMTSortRef mkSort(const QualType &Ty, unsigned BitWidth) {
+ if (Ty->isBooleanType())
+ return getBoolSort();
+
+ if (Ty->isRealFloatingType())
+ return getFloatSort(BitWidth);
+
+ return getBitvectorSort(BitWidth);
+ }
+
+ /// Constructs an SMTExprRef from an unary operator.
+ SMTExprRef fromUnOp(const UnaryOperator::Opcode Op, const SMTExprRef &Exp) {
+ switch (Op) {
+ case UO_Minus:
+ return mkBVNeg(Exp);
+
+ case UO_Not:
+ return mkBVNot(Exp);
+
+ case UO_LNot:
+ return mkNot(Exp);
+
+ default:;
+ }
+ llvm_unreachable("Unimplemented opcode");
+ }
+
+ /// Constructs an SMTExprRef from a floating-point unary operator.
+ SMTExprRef fromFloatUnOp(const UnaryOperator::Opcode Op,
+ const SMTExprRef &Exp) {
+ switch (Op) {
+ case UO_Minus:
+ return mkFPNeg(Exp);
+
+ case UO_LNot:
+ return fromUnOp(Op, Exp);
+
+ default:;
+ }
+ llvm_unreachable("Unimplemented opcode");
+ }
+
+ /// Construct an SMTExprRef from a n-ary binary operator.
+ SMTExprRef fromNBinOp(const BinaryOperator::Opcode Op,
+ const std::vector<SMTExprRef> &ASTs) {
+ assert(!ASTs.empty());
+
+ if (Op != BO_LAnd && Op != BO_LOr)
+ llvm_unreachable("Unimplemented opcode");
+
+ SMTExprRef res = ASTs.front();
+ for (std::size_t i = 1; i < ASTs.size(); ++i)
+ res = (Op == BO_LAnd) ? mkAnd(res, ASTs[i]) : mkOr(res, ASTs[i]);
+ return res;
+ }
+
+ /// Construct an SMTExprRef from a binary operator.
+ SMTExprRef fromBinOp(const SMTExprRef &LHS, const BinaryOperator::Opcode Op,
+ const SMTExprRef &RHS, bool isSigned) {
+ assert(*getSort(LHS) == *getSort(RHS) && "AST's must have the same sort!");
+
+ switch (Op) {
+ // Multiplicative operators
+ case BO_Mul:
+ return mkBVMul(LHS, RHS);
+
+ case BO_Div:
+ return isSigned ? mkBVSDiv(LHS, RHS) : mkBVUDiv(LHS, RHS);
+
+ case BO_Rem:
+ return isSigned ? mkBVSRem(LHS, RHS) : mkBVURem(LHS, RHS);
+
+ // Additive operators
+ case BO_Add:
+ return mkBVAdd(LHS, RHS);
+
+ case BO_Sub:
+ return mkBVSub(LHS, RHS);
+
+ // Bitwise shift operators
+ case BO_Shl:
+ return mkBVShl(LHS, RHS);
+
+ case BO_Shr:
+ return isSigned ? mkBVAshr(LHS, RHS) : mkBVLshr(LHS, RHS);
+
+ // Relational operators
+ case BO_LT:
+ return isSigned ? mkBVSlt(LHS, RHS) : mkBVUlt(LHS, RHS);
+
+ case BO_GT:
+ return isSigned ? mkBVSgt(LHS, RHS) : mkBVUgt(LHS, RHS);
+
+ case BO_LE:
+ return isSigned ? mkBVSle(LHS, RHS) : mkBVUle(LHS, RHS);
+
+ case BO_GE:
+ return isSigned ? mkBVSge(LHS, RHS) : mkBVUge(LHS, RHS);
+
+ // Equality operators
+ case BO_EQ:
+ return mkEqual(LHS, RHS);
+
+ case BO_NE:
+ return fromUnOp(UO_LNot, fromBinOp(LHS, BO_EQ, RHS, isSigned));
+
+ // Bitwise operators
+ case BO_And:
+ return mkBVAnd(LHS, RHS);
+
+ case BO_Xor:
+ return mkBVXor(LHS, RHS);
+
+ case BO_Or:
+ return mkBVOr(LHS, RHS);
+
+ // Logical operators
+ case BO_LAnd:
+ return mkAnd(LHS, RHS);
+
+ case BO_LOr:
+ return mkOr(LHS, RHS);
+
+ default:;
+ }
+ llvm_unreachable("Unimplemented opcode");
+ }
+
+ /// Construct an SMTExprRef from a special floating-point binary operator.
+ SMTExprRef fromFloatSpecialBinOp(const SMTExprRef &LHS,
+ const BinaryOperator::Opcode Op,
+ const llvm::APFloat::fltCategory &RHS) {
+ switch (Op) {
+ // Equality operators
+ case BO_EQ:
+ switch (RHS) {
+ case llvm::APFloat::fcInfinity:
+ return mkFPIsInfinite(LHS);
+
+ case llvm::APFloat::fcNaN:
+ return mkFPIsNaN(LHS);
+
+ case llvm::APFloat::fcNormal:
+ return mkFPIsNormal(LHS);
+
+ case llvm::APFloat::fcZero:
+ return mkFPIsZero(LHS);
+ }
+ break;
+
+ case BO_NE:
+ return fromFloatUnOp(UO_LNot, fromFloatSpecialBinOp(LHS, BO_EQ, RHS));
+
+ default:;
+ }
+
+ llvm_unreachable("Unimplemented opcode");
+ }
+
+ /// Construct an SMTExprRef from a floating-point binary operator.
+ SMTExprRef fromFloatBinOp(const SMTExprRef &LHS,
+ const BinaryOperator::Opcode Op,
+ const SMTExprRef &RHS) {
+ assert(*getSort(LHS) == *getSort(RHS) && "AST's must have the same sort!");
+
+ switch (Op) {
+ // Multiplicative operators
+ case BO_Mul:
+ return mkFPMul(LHS, RHS);
+
+ case BO_Div:
+ return mkFPDiv(LHS, RHS);
+
+ case BO_Rem:
+ return mkFPRem(LHS, RHS);
+
+ // Additive operators
+ case BO_Add:
+ return mkFPAdd(LHS, RHS);
+
+ case BO_Sub:
+ return mkFPSub(LHS, RHS);
+
+ // Relational operators
+ case BO_LT:
+ return mkFPLt(LHS, RHS);
+
+ case BO_GT:
+ return mkFPGt(LHS, RHS);
+
+ case BO_LE:
+ return mkFPLe(LHS, RHS);
+
+ case BO_GE:
+ return mkFPGe(LHS, RHS);
+
+ // Equality operators
+ case BO_EQ:
+ return mkFPEqual(LHS, RHS);
+
+ case BO_NE:
+ return fromFloatUnOp(UO_LNot, fromFloatBinOp(LHS, BO_EQ, RHS));
+
+ // Logical operators
+ case BO_LAnd:
+ case BO_LOr:
+ return fromBinOp(LHS, Op, RHS, false);
+
+ default:;
+ }
+
+ llvm_unreachable("Unimplemented opcode");
+ }
+
+ /// Construct an SMTExprRef from a QualType FromTy to a QualType ToTy, and
+ /// their bit widths.
+ SMTExprRef fromCast(const SMTExprRef &Exp, QualType ToTy, uint64_t ToBitWidth,
+ QualType FromTy, uint64_t FromBitWidth) {
+ if ((FromTy->isIntegralOrEnumerationType() &&
+ ToTy->isIntegralOrEnumerationType()) ||
+ (FromTy->isAnyPointerType() ^ ToTy->isAnyPointerType()) ||
+ (FromTy->isBlockPointerType() ^ ToTy->isBlockPointerType()) ||
+ (FromTy->isReferenceType() ^ ToTy->isReferenceType())) {
+
+ if (FromTy->isBooleanType()) {
+ assert(ToBitWidth > 0 && "BitWidth must be positive!");
+ return mkIte(Exp, mkBitvector(llvm::APSInt("1"), ToBitWidth),
+ mkBitvector(llvm::APSInt("0"), ToBitWidth));
+ }
+
+ if (ToBitWidth > FromBitWidth)
+ return FromTy->isSignedIntegerOrEnumerationType()
+ ? mkBVSignExt(ToBitWidth - FromBitWidth, Exp)
+ : mkBVZeroExt(ToBitWidth - FromBitWidth, Exp);
+
+ if (ToBitWidth < FromBitWidth)
+ return mkBVExtract(ToBitWidth - 1, 0, Exp);
+
+ // Both are bitvectors with the same width, ignore the type cast
+ return Exp;
+ }
+
+ if (FromTy->isRealFloatingType() && ToTy->isRealFloatingType()) {
+ if (ToBitWidth != FromBitWidth)
+ return mkFPtoFP(Exp, getFloatSort(ToBitWidth));
+
+ return Exp;
+ }
+
+ if (FromTy->isIntegralOrEnumerationType() && ToTy->isRealFloatingType()) {
+ SMTSortRef Sort = getFloatSort(ToBitWidth);
+ return FromTy->isSignedIntegerOrEnumerationType() ? mkFPtoSBV(Exp, Sort)
+ : mkFPtoUBV(Exp, Sort);
+ }
+
+ if (FromTy->isRealFloatingType() && ToTy->isIntegralOrEnumerationType())
+ return ToTy->isSignedIntegerOrEnumerationType()
+ ? mkSBVtoFP(Exp, ToBitWidth)
+ : mkUBVtoFP(Exp, ToBitWidth);
+
+ llvm_unreachable("Unsupported explicit type cast!");
+ }
+
+ // Callback function for doCast parameter on APSInt type.
+ llvm::APSInt castAPSInt(const llvm::APSInt &V, QualType ToTy,
+ uint64_t ToWidth, QualType FromTy,
+ uint64_t FromWidth) {
+ APSIntType TargetType(ToWidth, !ToTy->isSignedIntegerOrEnumerationType());
+ return TargetType.convert(V);
+ }
+
+ // Generate an SMTExprRef that represents the given symbolic expression.
+ // Sets the hasComparison parameter if the expression has a comparison
+ // operator.
+ // Sets the RetTy parameter to the final return type after promotions and
+ // casts.
+ SMTExprRef getExpr(ASTContext &Ctx, SymbolRef Sym, QualType *RetTy = nullptr,
+ bool *hasComparison = nullptr) {
+ if (hasComparison) {
+ *hasComparison = false;
+ }
+
+ return getSymExpr(Ctx, Sym, RetTy, hasComparison);
+ }
+
+ // Generate an SMTExprRef that compares the expression to zero.
+ SMTExprRef getZeroExpr(ASTContext &Ctx, const SMTExprRef &Exp, QualType Ty,
+ bool Assumption) {
+
+ if (Ty->isRealFloatingType()) {
+ llvm::APFloat Zero =
+ llvm::APFloat::getZero(Ctx.getFloatTypeSemantics(Ty));
+ return fromFloatBinOp(Exp, Assumption ? BO_EQ : BO_NE, fromAPFloat(Zero));
+ }
+
+ if (Ty->isIntegralOrEnumerationType() || Ty->isAnyPointerType() ||
+ Ty->isBlockPointerType() || Ty->isReferenceType()) {
+
+ // Skip explicit comparison for boolean types
+ bool isSigned = Ty->isSignedIntegerOrEnumerationType();
+ if (Ty->isBooleanType())
+ return Assumption ? fromUnOp(UO_LNot, Exp) : Exp;
+
+ return fromBinOp(Exp, Assumption ? BO_EQ : BO_NE,
+ fromInt("0", Ctx.getTypeSize(Ty)), isSigned);
+ }
+
+ llvm_unreachable("Unsupported type for zero value!");
+ }
+
+ // Recursive implementation to unpack and generate symbolic expression.
+ // Sets the hasComparison and RetTy parameters. See getExpr().
+ SMTExprRef getSymExpr(ASTContext &Ctx, SymbolRef Sym, QualType *RetTy,
+ bool *hasComparison) {
+ if (const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
+ if (RetTy)
+ *RetTy = Sym->getType();
+
+ return fromData(SD->getSymbolID(), Sym->getType(),
+ Ctx.getTypeSize(Sym->getType()));
+ }
+
+ if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
+ if (RetTy)
+ *RetTy = Sym->getType();
+
+ QualType FromTy;
+ SMTExprRef Exp =
+ getSymExpr(Ctx, SC->getOperand(), &FromTy, hasComparison);
+ // Casting an expression with a comparison invalidates it. Note that this
+ // must occur after the recursive call above.
+ // e.g. (signed char) (x > 0)
+ if (hasComparison)
+ *hasComparison = false;
+ return getCastExpr(Ctx, Exp, FromTy, Sym->getType());
+ }
+
+ if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
+ SMTExprRef Exp = getSymBinExpr(Ctx, BSE, hasComparison, RetTy);
+ // Set the hasComparison parameter, in post-order traversal order.
+ if (hasComparison)
+ *hasComparison = BinaryOperator::isComparisonOp(BSE->getOpcode());
+ return Exp;
+ }
+
+ llvm_unreachable("Unsupported SymbolRef type!");
+ }
+
+ // Wrapper to generate SMTExprRef from SymbolCast data.
+ SMTExprRef getCastExpr(ASTContext &Ctx, const SMTExprRef &Exp,
+ QualType FromTy, QualType ToTy) {
+ return fromCast(Exp, ToTy, Ctx.getTypeSize(ToTy), FromTy,
+ Ctx.getTypeSize(FromTy));
+ }
+
+ // Wrapper to generate SMTExprRef from BinarySymExpr.
+ // Sets the hasComparison and RetTy parameters. See getSMTExprRef().
+ SMTExprRef getSymBinExpr(ASTContext &Ctx, const BinarySymExpr *BSE,
+ bool *hasComparison, QualType *RetTy) {
+ QualType LTy, RTy;
+ BinaryOperator::Opcode Op = BSE->getOpcode();
+
+ if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
+ SMTExprRef LHS = getSymExpr(Ctx, SIE->getLHS(), &LTy, hasComparison);
+ llvm::APSInt NewRInt;
+ std::tie(NewRInt, RTy) = fixAPSInt(Ctx, SIE->getRHS());
+ SMTExprRef RHS = fromAPSInt(NewRInt);
+ return getBinExpr(Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
+ }
+
+ if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
+ llvm::APSInt NewLInt;
+ std::tie(NewLInt, LTy) = fixAPSInt(Ctx, ISE->getLHS());
+ SMTExprRef LHS = fromAPSInt(NewLInt);
+ SMTExprRef RHS = getSymExpr(Ctx, ISE->getRHS(), &RTy, hasComparison);
+ return getBinExpr(Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
+ }
+
+ if (const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
+ SMTExprRef LHS = getSymExpr(Ctx, SSM->getLHS(), &LTy, hasComparison);
+ SMTExprRef RHS = getSymExpr(Ctx, SSM->getRHS(), &RTy, hasComparison);
+ return getBinExpr(Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
+ }
+
+ llvm_unreachable("Unsupported BinarySymExpr type!");
+ }
+
+ // Wrapper to generate SMTExprRef from unpacked binary symbolic expression.
+ // Sets the RetTy parameter. See getSMTExprRef().
+ SMTExprRef getBinExpr(ASTContext &Ctx, const SMTExprRef &LHS, QualType LTy,
+ BinaryOperator::Opcode Op, const SMTExprRef &RHS,
+ QualType RTy, QualType *RetTy) {
+ SMTExprRef NewLHS = LHS;
+ SMTExprRef NewRHS = RHS;
+ doTypeConversion(Ctx, NewLHS, NewRHS, LTy, RTy);
+
+ // Update the return type parameter if the output type has changed.
+ if (RetTy) {
+ // A boolean result can be represented as an integer type in C/C++, but at
+ // this point we only care about the SMT sorts. Set it as a boolean type
+ // to avoid subsequent SMT errors.
+ if (BinaryOperator::isComparisonOp(Op) ||
+ BinaryOperator::isLogicalOp(Op)) {
+ *RetTy = Ctx.BoolTy;
+ } else {
+ *RetTy = LTy;
+ }
+
+ // If the two operands are pointers and the operation is a subtraction,
+ // the result is of type ptrdiff_t, which is signed
+ if (LTy->isAnyPointerType() && RTy->isAnyPointerType() && Op == BO_Sub) {
+ *RetTy = Ctx.getPointerDiffType();
+ }
+ }
+
+ return LTy->isRealFloatingType()
+ ? fromFloatBinOp(NewLHS, Op, NewRHS)
+ : fromBinOp(NewLHS, Op, NewRHS,
+ LTy->isSignedIntegerOrEnumerationType());
+ }
+
+ // Wrapper to generate SMTExprRef from a range. If From == To, an equality
+ // will be created instead.
+ SMTExprRef getRangeExpr(ASTContext &Ctx, SymbolRef Sym,
+ const llvm::APSInt &From, const llvm::APSInt &To,
+ bool InRange) {
+ // Convert lower bound
+ QualType FromTy;
+ llvm::APSInt NewFromInt;
+ std::tie(NewFromInt, FromTy) = fixAPSInt(Ctx, From);
+ SMTExprRef FromExp = fromAPSInt(NewFromInt);
+
+ // Convert symbol
+ QualType SymTy;
+ SMTExprRef Exp = getExpr(Ctx, Sym, &SymTy);
+
+ // Construct single (in)equality
+ if (From == To)
+ return getBinExpr(Ctx, Exp, SymTy, InRange ? BO_EQ : BO_NE, FromExp,
+ FromTy, /*RetTy=*/nullptr);
+
+ QualType ToTy;
+ llvm::APSInt NewToInt;
+ std::tie(NewToInt, ToTy) = fixAPSInt(Ctx, To);
+ SMTExprRef ToExp = fromAPSInt(NewToInt);
+ assert(FromTy == ToTy && "Range values have different types!");
+
+ // Construct two (in)equalities, and a logical and/or
+ SMTExprRef LHS = getBinExpr(Ctx, Exp, SymTy, InRange ? BO_GE : BO_LT,
+ FromExp, FromTy, /*RetTy=*/nullptr);
+ SMTExprRef RHS =
+ getBinExpr(Ctx, Exp, SymTy, InRange ? BO_LE : BO_GT, ToExp, ToTy,
+ /*RetTy=*/nullptr);
+
+ return fromBinOp(LHS, InRange ? BO_LAnd : BO_LOr, RHS,
+ SymTy->isSignedIntegerOrEnumerationType());
+ }
+
+ // Recover the QualType of an APSInt.
+ // TODO: Refactor to put elsewhere
+ QualType getAPSIntType(ASTContext &Ctx, const llvm::APSInt &Int) {
+ return Ctx.getIntTypeForBitwidth(Int.getBitWidth(), Int.isSigned());
+ }
+
+ // Get the QualTy for the input APSInt, and fix it if it has a bitwidth of 1.
+ std::pair<llvm::APSInt, QualType> fixAPSInt(ASTContext &Ctx,
+ const llvm::APSInt &Int) {
+ llvm::APSInt NewInt;
+
+ // FIXME: This should be a cast from a 1-bit integer type to a boolean type,
+ // but the former is not available in Clang. Instead, extend the APSInt
+ // directly.
+ if (Int.getBitWidth() == 1 && getAPSIntType(Ctx, Int).isNull()) {
+ NewInt = Int.extend(Ctx.getTypeSize(Ctx.BoolTy));
+ } else
+ NewInt = Int;
+
+ return std::make_pair(NewInt, getAPSIntType(Ctx, NewInt));
+ }
+
+ // Perform implicit type conversion on binary symbolic expressions.
+ // May modify all input parameters.
+ // TODO: Refactor to use built-in conversion functions
+ void doTypeConversion(ASTContext &Ctx, SMTExprRef &LHS, SMTExprRef &RHS,
+ QualType &LTy, QualType &RTy) {
+ assert(!LTy.isNull() && !RTy.isNull() && "Input type is null!");
+
+ // Perform type conversion
+ if ((LTy->isIntegralOrEnumerationType() &&
+ RTy->isIntegralOrEnumerationType()) &&
+ (LTy->isArithmeticType() && RTy->isArithmeticType())) {
+ doIntTypeConversion<SMTExprRef, &SMTSolver::fromCast>(Ctx, LHS, LTy, RHS,
+ RTy);
+ return;
+ }
+
+ if (LTy->isRealFloatingType() || RTy->isRealFloatingType()) {
+ doFloatTypeConversion<SMTExprRef, &SMTSolver::fromCast>(Ctx, LHS, LTy,
+ RHS, RTy);
+ return;
+ }
+
+ if ((LTy->isAnyPointerType() || RTy->isAnyPointerType()) ||
+ (LTy->isBlockPointerType() || RTy->isBlockPointerType()) ||
+ (LTy->isReferenceType() || RTy->isReferenceType())) {
+ // TODO: Refactor to Sema::FindCompositePointerType(), and
+ // Sema::CheckCompareOperands().
+
+ uint64_t LBitWidth = Ctx.getTypeSize(LTy);
+ uint64_t RBitWidth = Ctx.getTypeSize(RTy);
+
+ // Cast the non-pointer type to the pointer type.
+ // TODO: Be more strict about this.
+ if ((LTy->isAnyPointerType() ^ RTy->isAnyPointerType()) ||
+ (LTy->isBlockPointerType() ^ RTy->isBlockPointerType()) ||
+ (LTy->isReferenceType() ^ RTy->isReferenceType())) {
+ if (LTy->isNullPtrType() || LTy->isBlockPointerType() ||
+ LTy->isReferenceType()) {
+ LHS = fromCast(LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = RTy;
+ } else {
+ RHS = fromCast(RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = LTy;
+ }
+ }
+
+ // Cast the void pointer type to the non-void pointer type.
+ // For void types, this assumes that the casted value is equal to the
+ // value of the original pointer, and does not account for alignment
+ // requirements.
+ if (LTy->isVoidPointerType() ^ RTy->isVoidPointerType()) {
+ assert((Ctx.getTypeSize(LTy) == Ctx.getTypeSize(RTy)) &&
+ "Pointer types have different bitwidths!");
+ if (RTy->isVoidPointerType())
+ RTy = LTy;
+ else
+ LTy = RTy;
+ }
+
+ if (LTy == RTy)
+ return;
+ }
+
+ // Fallback: for the solver, assume that these types don't really matter
+ if ((LTy.getCanonicalType() == RTy.getCanonicalType()) ||
+ (LTy->isObjCObjectPointerType() && RTy->isObjCObjectPointerType())) {
+ LTy = RTy;
+ return;
+ }
+
+ // TODO: Refine behavior for invalid type casts
+ }
+
+ // Perform implicit integer type conversion.
+ // May modify all input parameters.
+ // TODO: Refactor to use Sema::handleIntegerConversion()
+ template <typename T, T (SMTSolver::*doCast)(const T &, QualType, uint64_t,
+ QualType, uint64_t)>
+ void doIntTypeConversion(ASTContext &Ctx, T &LHS, QualType &LTy, T &RHS,
+ QualType &RTy) {
+
+ uint64_t LBitWidth = Ctx.getTypeSize(LTy);
+ uint64_t RBitWidth = Ctx.getTypeSize(RTy);
+
+ assert(!LTy.isNull() && !RTy.isNull() && "Input type is null!");
+ // Always perform integer promotion before checking type equality.
+ // Otherwise, e.g. (bool) a + (bool) b could trigger a backend assertion
+ if (LTy->isPromotableIntegerType()) {
+ QualType NewTy = Ctx.getPromotedIntegerType(LTy);
+ uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
+ LHS = (this->*doCast)(LHS, NewTy, NewBitWidth, LTy, LBitWidth);
+ LTy = NewTy;
+ LBitWidth = NewBitWidth;
+ }
+ if (RTy->isPromotableIntegerType()) {
+ QualType NewTy = Ctx.getPromotedIntegerType(RTy);
+ uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
+ RHS = (this->*doCast)(RHS, NewTy, NewBitWidth, RTy, RBitWidth);
+ RTy = NewTy;
+ RBitWidth = NewBitWidth;
+ }
+
+ if (LTy == RTy)
+ return;
+
+ // Perform integer type conversion
+ // Note: Safe to skip updating bitwidth because this must terminate
+ bool isLSignedTy = LTy->isSignedIntegerOrEnumerationType();
+ bool isRSignedTy = RTy->isSignedIntegerOrEnumerationType();
+
+ int order = Ctx.getIntegerTypeOrder(LTy, RTy);
+ if (isLSignedTy == isRSignedTy) {
+ // Same signedness; use the higher-ranked type
+ if (order == 1) {
+ RHS = (this->*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = LTy;
+ } else {
+ LHS = (this->*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = RTy;
+ }
+ } else if (order != (isLSignedTy ? 1 : -1)) {
+ // The unsigned type has greater than or equal rank to the
+ // signed type, so use the unsigned type
+ if (isRSignedTy) {
+ RHS = (this->*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = LTy;
+ } else {
+ LHS = (this->*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = RTy;
+ }
+ } else if (LBitWidth != RBitWidth) {
+ // The two types are different widths; if we are here, that
+ // means the signed type is larger than the unsigned type, so
+ // use the signed type.
+ if (isLSignedTy) {
+ RHS = (this->*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = LTy;
+ } else {
+ LHS = (this->*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = RTy;
+ }
+ } else {
+ // The signed type is higher-ranked than the unsigned type,
+ // but isn't actually any bigger (like unsigned int and long
+ // on most 32-bit systems). Use the unsigned type corresponding
+ // to the signed type.
+ QualType NewTy =
+ Ctx.getCorrespondingUnsignedType(isLSignedTy ? LTy : RTy);
+ RHS = (this->*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = NewTy;
+ LHS = (this->*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = NewTy;
+ }
+ }
+
+ // Perform implicit floating-point type conversion.
+ // May modify all input parameters.
+ // TODO: Refactor to use Sema::handleFloatConversion()
+ template <typename T, T (SMTSolver::*doCast)(const T &, QualType, uint64_t,
+ QualType, uint64_t)>
+ void doFloatTypeConversion(ASTContext &Ctx, T &LHS, QualType &LTy, T &RHS,
+ QualType &RTy) {
+
+ uint64_t LBitWidth = Ctx.getTypeSize(LTy);
+ uint64_t RBitWidth = Ctx.getTypeSize(RTy);
+
+ // Perform float-point type promotion
+ if (!LTy->isRealFloatingType()) {
+ LHS = (this->*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = RTy;
+ LBitWidth = RBitWidth;
+ }
+ if (!RTy->isRealFloatingType()) {
+ RHS = (this->*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = LTy;
+ RBitWidth = LBitWidth;
+ }
+
+ if (LTy == RTy)
+ return;
+
+ // If we have two real floating types, convert the smaller operand to the
+ // bigger result
+ // Note: Safe to skip updating bitwidth because this must terminate
+ int order = Ctx.getFloatingTypeOrder(LTy, RTy);
+ if (order > 0) {
+ RHS = (this->*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
+ RTy = LTy;
+ } else if (order == 0) {
+ LHS = (this->*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
+ LTy = RTy;
+ } else {
+ llvm_unreachable("Unsupported floating-point type cast!");
+ }
+ }
+
+ // Returns a boolean sort.
+ virtual SMTSortRef getBoolSort() = 0;
+
+ // Returns an appropriate bitvector sort for the given bitwidth.
+ virtual SMTSortRef getBitvectorSort(const unsigned BitWidth) = 0;
+
+ // Returns a floating-point sort of width 16
+ virtual SMTSortRef getFloat16Sort() = 0;
+
+ // Returns a floating-point sort of width 32
+ virtual SMTSortRef getFloat32Sort() = 0;
+
+ // Returns a floating-point sort of width 64
+ virtual SMTSortRef getFloat64Sort() = 0;
+
+ // Returns a floating-point sort of width 128
+ virtual SMTSortRef getFloat128Sort() = 0;
+
+ // Returns an appropriate sort for the given AST.
+ virtual SMTSortRef getSort(const SMTExprRef &AST) = 0;
+
+ // Returns a new SMTExprRef from an SMTExpr
+ virtual SMTExprRef newExprRef(const SMTExpr &E) const = 0;
+
+ /// Given a constraint, adds it to the solver
+ virtual void addConstraint(const SMTExprRef &Exp) const = 0;
+
+ /// Creates a bitvector addition operation
+ virtual SMTExprRef mkBVAdd(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector subtraction operation
+ virtual SMTExprRef mkBVSub(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector multiplication operation
+ virtual SMTExprRef mkBVMul(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector signed modulus operation
+ virtual SMTExprRef mkBVSRem(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector unsigned modulus operation
+ virtual SMTExprRef mkBVURem(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector signed division operation
+ virtual SMTExprRef mkBVSDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector unsigned division operation
+ virtual SMTExprRef mkBVUDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector logical shift left operation
+ virtual SMTExprRef mkBVShl(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector arithmetic shift right operation
+ virtual SMTExprRef mkBVAshr(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector logical shift right operation
+ virtual SMTExprRef mkBVLshr(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector negation operation
+ virtual SMTExprRef mkBVNeg(const SMTExprRef &Exp) = 0;
+
+ /// Creates a bitvector not operation
+ virtual SMTExprRef mkBVNot(const SMTExprRef &Exp) = 0;
+
+ /// Creates a bitvector xor operation
+ virtual SMTExprRef mkBVXor(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector or operation
+ virtual SMTExprRef mkBVOr(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector and operation
+ virtual SMTExprRef mkBVAnd(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector unsigned less-than operation
+ virtual SMTExprRef mkBVUlt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector signed less-than operation
+ virtual SMTExprRef mkBVSlt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector unsigned greater-than operation
+ virtual SMTExprRef mkBVUgt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector signed greater-than operation
+ virtual SMTExprRef mkBVSgt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector unsigned less-equal-than operation
+ virtual SMTExprRef mkBVUle(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector signed less-equal-than operation
+ virtual SMTExprRef mkBVSle(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector unsigned greater-equal-than operation
+ virtual SMTExprRef mkBVUge(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a bitvector signed greater-equal-than operation
+ virtual SMTExprRef mkBVSge(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a boolean not operation
+ virtual SMTExprRef mkNot(const SMTExprRef &Exp) = 0;
+
+ /// Creates a boolean equality operation
+ virtual SMTExprRef mkEqual(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a boolean and operation
+ virtual SMTExprRef mkAnd(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a boolean or operation
+ virtual SMTExprRef mkOr(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a boolean ite operation
+ virtual SMTExprRef mkIte(const SMTExprRef &Cond, const SMTExprRef &T,
+ const SMTExprRef &F) = 0;
+
+ /// Creates a bitvector sign extension operation
+ virtual SMTExprRef mkBVSignExt(unsigned i, const SMTExprRef &Exp) = 0;
+
+ /// Creates a bitvector zero extension operation
+ virtual SMTExprRef mkBVZeroExt(unsigned i, const SMTExprRef &Exp) = 0;
+
+ /// Creates a bitvector extract operation
+ virtual SMTExprRef mkBVExtract(unsigned High, unsigned Low,
+ const SMTExprRef &Exp) = 0;
+
+ /// Creates a bitvector concat operation
+ virtual SMTExprRef mkBVConcat(const SMTExprRef &LHS,
+ const SMTExprRef &RHS) = 0;
+
+ /// Creates a floating-point negation operation
+ virtual SMTExprRef mkFPNeg(const SMTExprRef &Exp) = 0;
+
+ /// Creates a floating-point isInfinite operation
+ virtual SMTExprRef mkFPIsInfinite(const SMTExprRef &Exp) = 0;
+
+ /// Creates a floating-point isNaN operation
+ virtual SMTExprRef mkFPIsNaN(const SMTExprRef &Exp) = 0;
+
+ /// Creates a floating-point isNormal operation
+ virtual SMTExprRef mkFPIsNormal(const SMTExprRef &Exp) = 0;
+
+ /// Creates a floating-point isZero operation
+ virtual SMTExprRef mkFPIsZero(const SMTExprRef &Exp) = 0;
+
+ /// Creates a floating-point multiplication operation
+ virtual SMTExprRef mkFPMul(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a floating-point division operation
+ virtual SMTExprRef mkFPDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a floating-point remainder operation
+ virtual SMTExprRef mkFPRem(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a floating-point addition operation
+ virtual SMTExprRef mkFPAdd(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a floating-point subtraction operation
+ virtual SMTExprRef mkFPSub(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a floating-point less-than operation
+ virtual SMTExprRef mkFPLt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a floating-point greater-than operation
+ virtual SMTExprRef mkFPGt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a floating-point less-than-or-equal operation
+ virtual SMTExprRef mkFPLe(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a floating-point greater-than-or-equal operation
+ virtual SMTExprRef mkFPGe(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
+
+ /// Creates a floating-point equality operation
+ virtual SMTExprRef mkFPEqual(const SMTExprRef &LHS,
+ const SMTExprRef &RHS) = 0;
+
+ /// Creates a floating-point conversion from floatint-point to floating-point
+ /// operation
+ virtual SMTExprRef mkFPtoFP(const SMTExprRef &From, const SMTSortRef &To) = 0;
+
+ /// Creates a floating-point conversion from floatint-point to signed
+ /// bitvector operation
+ virtual SMTExprRef mkFPtoSBV(const SMTExprRef &From,
+ const SMTSortRef &To) = 0;
+
+ /// Creates a floating-point conversion from floatint-point to unsigned
+ /// bitvector operation
+ virtual SMTExprRef mkFPtoUBV(const SMTExprRef &From,
+ const SMTSortRef &To) = 0;
+
+ /// Creates a floating-point conversion from signed bitvector to
+ /// floatint-point operation
+ virtual SMTExprRef mkSBVtoFP(const SMTExprRef &From, unsigned ToWidth) = 0;
+
+ /// Creates a floating-point conversion from unsigned bitvector to
+ /// floatint-point operation
+ virtual SMTExprRef mkUBVtoFP(const SMTExprRef &From, unsigned ToWidth) = 0;
+
+ /// Creates a new symbol, given a name and a sort
+ virtual SMTExprRef mkSymbol(const char *Name, SMTSortRef Sort) = 0;
+
+ // Returns an appropriate floating-point rounding mode.
+ virtual SMTExprRef getFloatRoundingMode() = 0;
+
+ // If the a model is available, returns the value of a given bitvector symbol
+ virtual llvm::APSInt getBitvector(const SMTExprRef &Exp, unsigned BitWidth,
+ bool isUnsigned) = 0;
+
+ // If the a model is available, returns the value of a given boolean symbol
+ virtual bool getBoolean(const SMTExprRef &Exp) = 0;
+
+ /// Constructs an SMTExprRef from a boolean.
+ virtual SMTExprRef mkBoolean(const bool b) = 0;
+
+ /// Constructs an SMTExprRef from a finite APFloat.
+ virtual SMTExprRef mkFloat(const llvm::APFloat Float) = 0;
+
+ /// Constructs an SMTExprRef from an APSInt and its bit width
+ virtual SMTExprRef mkBitvector(const llvm::APSInt Int, unsigned BitWidth) = 0;
+
+ /// Given an expression, extract the value of this operand in the model.
+ virtual bool getInterpretation(const SMTExprRef &Exp, llvm::APSInt &Int) = 0;
+
+ /// Given an expression extract the value of this operand in the model.
+ virtual bool getInterpretation(const SMTExprRef &Exp,
+ llvm::APFloat &Float) = 0;
+
+ /// Construct an SMTExprRef value from a boolean.
+ virtual SMTExprRef fromBoolean(const bool Bool) = 0;
+
+ /// Construct an SMTExprRef value from a finite APFloat.
+ virtual SMTExprRef fromAPFloat(const llvm::APFloat &Float) = 0;
+
+ /// Construct an SMTExprRef value from an APSInt.
+ virtual SMTExprRef fromAPSInt(const llvm::APSInt &Int) = 0;
+
+ /// Construct an SMTExprRef value from an integer.
+ virtual SMTExprRef fromInt(const char *Int, uint64_t BitWidth) = 0;
+
+ /// Construct an SMTExprRef from a SymbolData.
+ virtual SMTExprRef fromData(const SymbolID ID, const QualType &Ty,
+ uint64_t BitWidth) = 0;
+
+ /// Check if the constraints are satisfiable
+ virtual ConditionTruthVal check() const = 0;
+
+ /// Push the current solver state
+ virtual void push() = 0;
+
+ /// Pop the previous solver state
+ virtual void pop(unsigned NumStates = 1) = 0;
+
+ /// Reset the solver and remove all constraints.
+ virtual void reset() const = 0;
+
+ virtual void print(raw_ostream &OS) const = 0;
+};
+
+/// Shared pointer for SMTSolvers.
+using SMTSolverRef = std::shared_ptr<SMTSolver>;
+
+/// Convenience method to create and Z3Solver object
+std::unique_ptr<SMTSolver> CreateZ3Solver();
+
+} // namespace ento
+} // namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h
new file mode 100644
index 0000000000000..41ef573f0c713
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h
@@ -0,0 +1,91 @@
+//== SMTSort.h --------------------------------------------------*- 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 a SMT generic Sort API, which will be the base class
+// for every SMT solver sort specific class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSORT_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSORT_H
+
+#include "clang/Basic/TargetInfo.h"
+
+namespace clang {
+namespace ento {
+
+/// Generic base class for SMT sorts
+class SMTSort {
+public:
+ SMTSort() = default;
+ virtual ~SMTSort() = default;
+
+ /// Returns true if the sort is a bitvector, calls isBitvectorSortImpl().
+ virtual bool isBitvectorSort() const { return isBitvectorSortImpl(); }
+
+ /// Returns true if the sort is a floating-point, calls isFloatSortImpl().
+ virtual bool isFloatSort() const { return isFloatSortImpl(); }
+
+ /// Returns true if the sort is a boolean, calls isBooleanSortImpl().
+ virtual bool isBooleanSort() const { return isBooleanSortImpl(); }
+
+ /// Returns the bitvector size, fails if the sort is not a bitvector
+ /// Calls getBitvectorSortSizeImpl().
+ virtual unsigned getBitvectorSortSize() const {
+ assert(isBitvectorSort() && "Not a bitvector sort!");
+ unsigned Size = getBitvectorSortSizeImpl();
+ assert(Size && "Size is zero!");
+ return Size;
+ };
+
+ /// Returns the floating-point size, fails if the sort is not a floating-point
+ /// Calls getFloatSortSizeImpl().
+ virtual unsigned getFloatSortSize() const {
+ assert(isFloatSort() && "Not a floating-point sort!");
+ unsigned Size = getFloatSortSizeImpl();
+ assert(Size && "Size is zero!");
+ return Size;
+ };
+
+ friend bool operator==(SMTSort const &LHS, SMTSort const &RHS) {
+ return LHS.equal_to(RHS);
+ }
+
+ virtual void print(raw_ostream &OS) const = 0;
+
+ LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); }
+
+protected:
+ /// Query the SMT solver and returns true if two sorts are equal (same kind
+ /// and bit width). This does not check if the two sorts are the same objects.
+ virtual bool equal_to(SMTSort const &other) const = 0;
+
+ /// Query the SMT solver and checks if a sort is bitvector.
+ virtual bool isBitvectorSortImpl() const = 0;
+
+ /// Query the SMT solver and checks if a sort is floating-point.
+ virtual bool isFloatSortImpl() const = 0;
+
+ /// Query the SMT solver and checks if a sort is boolean.
+ virtual bool isBooleanSortImpl() const = 0;
+
+ /// Query the SMT solver and returns the sort bit width.
+ virtual unsigned getBitvectorSortSizeImpl() const = 0;
+
+ /// Query the SMT solver and returns the sort bit width.
+ virtual unsigned getFloatSortSizeImpl() const = 0;
+};
+
+/// Shared pointer for SMTSorts, used by SMTSolver API.
+using SMTSortRef = std::shared_ptr<SMTSort>;
+
+} // namespace ento
+} // namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index d58d0a690c88e..31300d69f2ff7 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -16,21 +16,43 @@
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALBUILDER_H
#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "llvm/ADT/ImmutableList.h"
+#include "llvm/ADT/Optional.h"
+#include <cstdint>
namespace clang {
+class BlockDecl;
class CXXBoolLiteralExpr;
+class CXXMethodDecl;
+class CXXRecordDecl;
+class DeclaratorDecl;
+class FunctionDecl;
+class LocationContext;
+class StackFrameContext;
+class Stmt;
namespace ento {
+class ConditionTruthVal;
+class ProgramStateManager;
+class StoreRef;
+
class SValBuilder {
virtual void anchor();
+
protected:
ASTContext &Context;
@@ -62,14 +84,12 @@ public:
public:
SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
ProgramStateManager &stateMgr)
- : Context(context), BasicVals(context, alloc),
- SymMgr(context, BasicVals, alloc),
- MemMgr(context, alloc),
- StateMgr(stateMgr),
- ArrayIndexTy(context.LongLongTy),
- ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {}
+ : Context(context), BasicVals(context, alloc),
+ SymMgr(context, BasicVals, alloc), MemMgr(context, alloc),
+ StateMgr(stateMgr), ArrayIndexTy(context.LongLongTy),
+ ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {}
- virtual ~SValBuilder() {}
+ virtual ~SValBuilder() = default;
bool haveSameType(const SymExpr *Sym1, const SymExpr *Sym2) {
return haveSameType(Sym1->getType(), Sym2->getType());
@@ -124,7 +144,12 @@ public:
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
SVal lhs, SVal rhs, QualType type);
-
+
+ /// \return Whether values in \p lhs and \p rhs are equal at \p state.
+ ConditionTruthVal areEqual(ProgramStateRef state, SVal lhs, SVal rhs);
+
+ SVal evalEQ(ProgramStateRef state, SVal lhs, SVal rhs);
+
DefinedOrUnknownSVal evalEQ(ProgramStateRef state, DefinedOrUnknownSVal lhs,
DefinedOrUnknownSVal rhs);
@@ -173,7 +198,7 @@ public:
/// Make a unique symbol for value of region.
DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedValueRegion *region);
- /// \brief Create a new symbol with a unique 'name'.
+ /// Create a new symbol with a unique 'name'.
///
/// We resort to conjured symbols when we cannot construct a derived symbol.
/// The advantage of symbols derived/built from other symbols is that we
@@ -188,12 +213,12 @@ public:
const LocationContext *LCtx,
QualType type,
unsigned count);
-
DefinedOrUnknownSVal conjureSymbolVal(const Stmt *stmt,
const LocationContext *LCtx,
QualType type,
unsigned visitCount);
- /// \brief Conjure a symbol representing heap allocated memory region.
+
+ /// Conjure a symbol representing heap allocated memory region.
///
/// Note, the expression should represent a location.
DefinedOrUnknownSVal getConjuredHeapSymbolVal(const Expr *E,
@@ -304,7 +329,7 @@ public:
NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
const SymExpr *rhs, QualType type);
- /// \brief Create a NonLoc value for cast.
+ /// Create a NonLoc value for cast.
NonLoc makeNonLoc(const SymExpr *operand, QualType fromTy, QualType toTy);
nonloc::ConcreteInt makeTruthVal(bool b, QualType type) {
@@ -342,6 +367,15 @@ public:
return loc::ConcreteInt(BasicVals.getValue(integer));
}
+ /// Make an SVal that represents the given symbol. This follows the convention
+ /// of representing Loc-type symbols (symbolic pointers and references)
+ /// as Loc values wrapping the symbol rather than as plain symbol values.
+ SVal makeSymbolVal(SymbolRef Sym) {
+ if (Loc::isLocType(Sym->getType()))
+ return makeLoc(Sym);
+ return nonloc::SymbolVal(Sym);
+ }
+
/// Return a memory region for the 'this' object reference.
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D,
const StackFrameContext *SFC);
@@ -355,8 +389,8 @@ SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
ASTContext &context,
ProgramStateManager &stateMgr);
-} // end GR namespace
+} // namespace ento
-} // end clang namespace
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALBUILDER_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index 06132587b4aaf..0fde63e9eb09b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -1,4 +1,4 @@
-//== SVals.h - Abstract Values for Static Analysis ---------*- C++ -*--==//
+//===- SVals.h - Abstract Values for Static Analysis ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,11 +16,18 @@
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableList.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
+#include <cstdint>
+#include <utility>
//==------------------------------------------------------------------------==//
// Base SVal types.
@@ -28,34 +35,40 @@
namespace clang {
+class CXXBaseSpecifier;
+class DeclaratorDecl;
+class FunctionDecl;
+class LabelDecl;
+
namespace ento {
+class BasicValueFactory;
class CompoundValData;
class LazyCompoundValData;
-class PointerToMemberData;
-class ProgramState;
-class BasicValueFactory;
class MemRegion;
-class TypedValueRegion;
-class MemRegionManager;
-class ProgramStateManager;
+class PointerToMemberData;
class SValBuilder;
+class TypedValueRegion;
namespace nonloc {
+
/// Sub-kinds for NonLoc values.
enum Kind {
#define NONLOC_SVAL(Id, Parent) Id ## Kind,
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
};
-}
+
+} // namespace nonloc
namespace loc {
+
/// Sub-kinds for Loc values.
enum Kind {
#define LOC_SVAL(Id, Parent) Id ## Kind,
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
};
-}
+
+} // namespace loc
/// SVal - This represents a symbolic expression, which can be either
/// an L-value or an R-value.
@@ -71,22 +84,21 @@ public:
enum { BaseBits = 2, BaseMask = 0x3 };
protected:
- const void *Data;
+ const void *Data = nullptr;
/// The lowest 2 bits are a BaseKind (0 -- 3).
/// The higher bits are an unsigned "kind" value.
- unsigned Kind;
+ unsigned Kind = 0;
explicit SVal(const void *d, bool isLoc, unsigned ValKind)
- : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
+ : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
- explicit SVal(BaseKind k, const void *D = nullptr)
- : Data(D), Kind(k) {}
+ explicit SVal(BaseKind k, const void *D = nullptr) : Data(D), Kind(k) {}
public:
- explicit SVal() : Data(nullptr), Kind(0) {}
+ explicit SVal() = default;
- /// \brief Convert to the specified SVal type, asserting that this SVal is of
+ /// Convert to the specified SVal type, asserting that this SVal is of
/// the desired type.
template<typename T>
T castAs() const {
@@ -94,7 +106,7 @@ public:
return *static_cast<const T *>(this);
}
- /// \brief Convert to the specified SVal type, returning None if this SVal is
+ /// Convert to the specified SVal type, returning None if this SVal is
/// not of the desired type.
template<typename T>
Optional<T> getAs() const {
@@ -103,38 +115,38 @@ public:
return *static_cast<const T *>(this);
}
- inline unsigned getRawKind() const { return Kind; }
- inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
- inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
+ unsigned getRawKind() const { return Kind; }
+ BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
+ unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
// This method is required for using SVal in a FoldingSetNode. It
// extracts a unique signature for this SVal object.
- inline void Profile(llvm::FoldingSetNodeID& ID) const {
+ void Profile(llvm::FoldingSetNodeID &ID) const {
ID.AddInteger((unsigned) getRawKind());
ID.AddPointer(Data);
}
- inline bool operator==(const SVal& R) const {
+ bool operator==(const SVal &R) const {
return getRawKind() == R.getRawKind() && Data == R.Data;
}
- inline bool operator!=(const SVal& R) const {
+ bool operator!=(const SVal &R) const {
return !(*this == R);
}
- inline bool isUnknown() const {
+ bool isUnknown() const {
return getRawKind() == UnknownValKind;
}
- inline bool isUndef() const {
+ bool isUndef() const {
return getRawKind() == UndefinedValKind;
}
- inline bool isUnknownOrUndef() const {
+ bool isUnknownOrUndef() const {
return getRawKind() <= UnknownValKind;
}
- inline bool isValid() const {
+ bool isValid() const {
return getRawKind() > UnknownValKind;
}
@@ -152,7 +164,7 @@ public:
/// Otherwise return 0.
const FunctionDecl *getAsFunctionDecl() const;
- /// \brief If this SVal is a location and wraps a symbol, return that
+ /// If this SVal is a location and wraps a symbol, return that
/// SymbolRef. Otherwise return 0.
///
/// Casts are ignored during lookup.
@@ -163,7 +175,7 @@ public:
/// Get the symbol in the SVal or its base region.
SymbolRef getLocSymbolInBase() const;
- /// \brief If this SVal wraps a symbol return that SymbolRef.
+ /// If this SVal wraps a symbol return that SymbolRef.
/// Otherwise, return 0.
///
/// Casts are ignored during lookup.
@@ -175,7 +187,7 @@ public:
/// return that expression. Otherwise return NULL.
const SymExpr *getAsSymbolicExpression() const;
- const SymExpr* getAsSymExpr() const;
+ const SymExpr *getAsSymExpr() const;
const MemRegion *getAsRegion() const;
@@ -183,7 +195,7 @@ public:
void dump() const;
SymExpr::symbol_iterator symbol_begin() const {
- const SymExpr *SE = getAsSymbolicExpression();
+ const SymExpr *SE = getAsSymbol(/*IncludeBaseRegions=*/true);
if (SE)
return SE->symbol_begin();
else
@@ -206,28 +218,28 @@ public:
private:
friend class SVal;
+
static bool isKind(const SVal& V) {
return V.getBaseKind() == UndefinedValKind;
}
};
class DefinedOrUnknownSVal : public SVal {
-private:
+public:
// We want calling these methods to be a compiler error since they are
// tautologically false.
bool isUndef() const = delete;
bool isValid() const = delete;
protected:
- DefinedOrUnknownSVal() {}
+ DefinedOrUnknownSVal() = default;
explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind)
- : SVal(d, isLoc, ValKind) {}
-
- explicit DefinedOrUnknownSVal(BaseKind k, void *D = nullptr)
- : SVal(k, D) {}
+ : SVal(d, isLoc, ValKind) {}
+ explicit DefinedOrUnknownSVal(BaseKind k, void *D = nullptr) : SVal(k, D) {}
private:
friend class SVal;
+
static bool isKind(const SVal& V) {
return !V.isUndef();
}
@@ -239,37 +251,43 @@ public:
private:
friend class SVal;
+
static bool isKind(const SVal &V) {
return V.getBaseKind() == UnknownValKind;
}
};
class DefinedSVal : public DefinedOrUnknownSVal {
-private:
+public:
// We want calling these methods to be a compiler error since they are
// tautologically true/false.
bool isUnknown() const = delete;
bool isUnknownOrUndef() const = delete;
bool isValid() const = delete;
+
protected:
- DefinedSVal() {}
+ DefinedSVal() = default;
explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind)
- : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
+ : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
+
private:
friend class SVal;
+
static bool isKind(const SVal& V) {
return !V.isUnknownOrUndef();
}
};
-
-/// \brief Represents an SVal that is guaranteed to not be UnknownVal.
+/// Represents an SVal that is guaranteed to not be UnknownVal.
class KnownSVal : public SVal {
- KnownSVal() {}
friend class SVal;
+
+ KnownSVal() = default;
+
static bool isKind(const SVal &V) {
return !V.isUnknown();
}
+
public:
KnownSVal(const DefinedSVal &V) : SVal(V) {}
KnownSVal(const UndefinedVal &V) : SVal(V) {}
@@ -277,20 +295,21 @@ public:
class NonLoc : public DefinedSVal {
protected:
- NonLoc() {}
+ NonLoc() = default;
explicit NonLoc(unsigned SubKind, const void *d)
- : DefinedSVal(d, false, SubKind) {}
+ : DefinedSVal(d, false, SubKind) {}
public:
void dumpToStream(raw_ostream &Out) const;
- static inline bool isCompoundType(QualType T) {
+ static bool isCompoundType(QualType T) {
return T->isArrayType() || T->isRecordType() ||
T->isComplexType() || T->isVectorType();
}
private:
friend class SVal;
+
static bool isKind(const SVal& V) {
return V.getBaseKind() == NonLocKind;
}
@@ -298,20 +317,21 @@ private:
class Loc : public DefinedSVal {
protected:
- Loc() {}
+ Loc() = default;
explicit Loc(unsigned SubKind, const void *D)
- : DefinedSVal(const_cast<void*>(D), true, SubKind) {}
+ : DefinedSVal(const_cast<void *>(D), true, SubKind) {}
public:
void dumpToStream(raw_ostream &Out) const;
- static inline bool isLocType(QualType T) {
+ static bool isLocType(QualType T) {
return T->isAnyPointerType() || T->isBlockPointerType() ||
T->isReferenceType() || T->isNullPtrType();
}
private:
friend class SVal;
+
static bool isKind(const SVal& V) {
return V.getBaseKind() == LocKind;
}
@@ -323,14 +343,17 @@ private:
namespace nonloc {
-/// \brief Represents symbolic expression.
+/// Represents symbolic expression that isn't a location.
class SymbolVal : public NonLoc {
public:
SymbolVal() = delete;
- SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) { assert(sym); }
+ SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {
+ assert(sym);
+ assert(!Loc::isLocType(sym->getType()));
+ }
SymbolRef getSymbol() const {
- return (const SymExpr*) Data;
+ return (const SymExpr *) Data;
}
bool isExpression() const {
@@ -339,6 +362,7 @@ public:
private:
friend class SVal;
+
static bool isKind(const SVal& V) {
return V.getBaseKind() == NonLocKind &&
V.getSubKind() == SymbolValKind;
@@ -349,13 +373,13 @@ private:
}
};
-/// \brief Value representing integer constant.
+/// Value representing integer constant.
class ConcreteInt : public NonLoc {
public:
explicit ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
const llvm::APSInt& getValue() const {
- return *static_cast<const llvm::APSInt*>(Data);
+ return *static_cast<const llvm::APSInt *>(Data);
}
// Transfer functions for binary/unary operations on ConcreteInts.
@@ -368,7 +392,9 @@ public:
private:
friend class SVal;
- ConcreteInt() {}
+
+ ConcreteInt() = default;
+
static bool isKind(const SVal& V) {
return V.getBaseKind() == NonLocKind &&
V.getSubKind() == ConcreteIntKind;
@@ -392,7 +418,6 @@ class LocAsInteger : public NonLoc {
}
public:
-
Loc getLoc() const {
const std::pair<SVal, uintptr_t> *D =
static_cast<const std::pair<SVal, uintptr_t> *>(Data);
@@ -414,7 +439,9 @@ public:
private:
friend class SVal;
- LocAsInteger() {}
+
+ LocAsInteger() = default;
+
static bool isKind(const SVal& V) {
return V.getBaseKind() == NonLocKind &&
V.getSubKind() == LocAsIntegerKind;
@@ -432,16 +459,19 @@ class CompoundVal : public NonLoc {
public:
const CompoundValData* getValue() const {
- return static_cast<const CompoundValData*>(Data);
+ return static_cast<const CompoundValData *>(Data);
}
- typedef llvm::ImmutableList<SVal>::iterator iterator;
+ using iterator = llvm::ImmutableList<SVal>::iterator;
+
iterator begin() const;
iterator end() const;
private:
friend class SVal;
- CompoundVal() {}
+
+ CompoundVal() = default;
+
static bool isKind(const SVal& V) {
return V.getBaseKind() == NonLocKind && V.getSubKind() == CompoundValKind;
}
@@ -455,30 +485,35 @@ class LazyCompoundVal : public NonLoc {
friend class ento::SValBuilder;
explicit LazyCompoundVal(const LazyCompoundValData *D)
- : NonLoc(LazyCompoundValKind, D) {}
+ : NonLoc(LazyCompoundValKind, D) {}
+
public:
const LazyCompoundValData *getCVData() const {
- return static_cast<const LazyCompoundValData*>(Data);
+ return static_cast<const LazyCompoundValData *>(Data);
}
+
const void *getStore() const;
const TypedValueRegion *getRegion() const;
private:
friend class SVal;
- LazyCompoundVal() {}
+
+ LazyCompoundVal() = default;
+
static bool isKind(const SVal& V) {
return V.getBaseKind() == NonLocKind &&
V.getSubKind() == LazyCompoundValKind;
}
+
static bool isKind(const NonLoc& V) {
return V.getSubKind() == LazyCompoundValKind;
}
};
-/// \brief Value representing pointer-to-member.
+/// Value representing pointer-to-member.
///
/// This value is qualified as NonLoc because neither loading nor storing
-/// operations are aplied to it. Instead, the analyzer uses the L-value coming
+/// operations are applied to it. Instead, the analyzer uses the L-value coming
/// from pointer-to-member applied to an object.
/// This SVal is represented by a DeclaratorDecl which can be a member function
/// pointer or a member data pointer and a list of CXXBaseSpecifiers. This list
@@ -488,28 +523,36 @@ class PointerToMember : public NonLoc {
friend class ento::SValBuilder;
public:
- typedef llvm::PointerUnion<const DeclaratorDecl *,
- const PointerToMemberData *> PTMDataType;
+ using PTMDataType =
+ llvm::PointerUnion<const DeclaratorDecl *, const PointerToMemberData *>;
+
const PTMDataType getPTMData() const {
return PTMDataType::getFromOpaqueValue(const_cast<void *>(Data));
}
+
bool isNullMemberPointer() const {
return getPTMData().isNull();
}
+
const DeclaratorDecl *getDecl() const;
+
template<typename AdjustedDecl>
- const AdjustedDecl* getDeclAs() const {
+ const AdjustedDecl *getDeclAs() const {
return dyn_cast_or_null<AdjustedDecl>(getDecl());
}
- typedef llvm::ImmutableList<const CXXBaseSpecifier *>::iterator iterator;
+
+ using iterator = llvm::ImmutableList<const CXXBaseSpecifier *>::iterator;
+
iterator begin() const;
iterator end() const;
private:
- explicit PointerToMember(const PTMDataType D)
- : NonLoc(PointerToMemberKind, D.getOpaqueValue()) {}
friend class SVal;
- PointerToMember() {}
+
+ PointerToMember() = default;
+ explicit PointerToMember(const PTMDataType D)
+ : NonLoc(PointerToMemberKind, D.getOpaqueValue()) {}
+
static bool isKind(const SVal& V) {
return V.getBaseKind() == NonLocKind &&
V.getSubKind() == PointerToMemberKind;
@@ -520,7 +563,7 @@ private:
}
};
-} // end namespace ento::nonloc
+} // namespace nonloc
//==------------------------------------------------------------------------==//
// Subclasses of Loc.
@@ -535,12 +578,14 @@ public:
}
const LabelDecl *getLabel() const {
- return static_cast<const LabelDecl*>(Data);
+ return static_cast<const LabelDecl *>(Data);
}
private:
friend class SVal;
- GotoLabel() {}
+
+ GotoLabel() = default;
+
static bool isKind(const SVal& V) {
return V.getBaseKind() == LocKind && V.getSubKind() == GotoLabelKind;
}
@@ -550,19 +595,18 @@ private:
}
};
-
class MemRegionVal : public Loc {
public:
explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionValKind, r) {
assert(r);
}
- /// \brief Get the underlining region.
- const MemRegion* getRegion() const {
- return static_cast<const MemRegion*>(Data);
+ /// Get the underlining region.
+ const MemRegion *getRegion() const {
+ return static_cast<const MemRegion *>(Data);
}
- /// \brief Get the underlining region and strip casts.
+ /// Get the underlining region and strip casts.
const MemRegion* stripCasts(bool StripBaseCasts = true) const;
template <typename REGION>
@@ -570,17 +614,19 @@ public:
return dyn_cast<REGION>(getRegion());
}
- inline bool operator==(const MemRegionVal& R) const {
+ bool operator==(const MemRegionVal &R) const {
return getRegion() == R.getRegion();
}
- inline bool operator!=(const MemRegionVal& R) const {
+ bool operator!=(const MemRegionVal &R) const {
return getRegion() != R.getRegion();
}
private:
friend class SVal;
- MemRegionVal() {}
+
+ MemRegionVal() = default;
+
static bool isKind(const SVal& V) {
return V.getBaseKind() == LocKind &&
V.getSubKind() == MemRegionValKind;
@@ -595,8 +641,8 @@ class ConcreteInt : public Loc {
public:
explicit ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
- const llvm::APSInt& getValue() const {
- return *static_cast<const llvm::APSInt*>(Data);
+ const llvm::APSInt &getValue() const {
+ return *static_cast<const llvm::APSInt *>(Data);
}
// Transfer functions for binary/unary operations on ConcreteInts.
@@ -605,7 +651,9 @@ public:
private:
friend class SVal;
- ConcreteInt() {}
+
+ ConcreteInt() = default;
+
static bool isKind(const SVal& V) {
return V.getBaseKind() == LocKind &&
V.getSubKind() == ConcreteIntKind;
@@ -616,11 +664,11 @@ private:
}
};
-} // end ento::loc namespace
+} // namespace loc
-} // end ento namespace
+} // namespace ento
-} // end clang namespace
+} // namespace clang
namespace llvm {
@@ -629,6 +677,6 @@ template <> struct isPodLike<clang::ento::SVal> {
static const bool value = true;
};
-} // end llvm namespace
+} // namespace llvm
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
index 2c9802bbc5360..d64b90e2d380a 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
@@ -75,6 +75,7 @@ protected:
// Internal implementation.
//===------------------------------------------------------------------===//
+ SValBuilder &getSValBuilder() const { return SVB; }
BasicValueFactory &getBasicVals() const { return SVB.getBasicValueFactory(); }
SymbolManager &getSymbolManager() const { return SVB.getSymbolManager(); }
@@ -85,8 +86,8 @@ private:
bool Assumption);
};
-} // end GR namespace
+} // end namespace ento
-} // end clang namespace
+} // end namespace clang
#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index 25d20a17afaa7..dc0644df8aabe 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -1,4 +1,4 @@
-//== Store.h - Interface for maps from Locations to Values ------*- C++ -*--==//
+//===- Store.h - Interface for maps from Locations to Values ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,27 +14,42 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STORE_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STORE_H
+#include "clang/AST/Type.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+#include <cstdint>
+#include <memory>
namespace clang {
-class Stmt;
+class ASTContext;
+class CastExpr;
+class CompoundLiteralExpr;
+class CXXBasePath;
+class Decl;
class Expr;
+class LocationContext;
class ObjCIvarDecl;
-class CXXBasePath;
class StackFrameContext;
namespace ento {
class CallEvent;
-class ProgramState;
class ProgramStateManager;
class ScanReachableSymbols;
+class SymbolReaper;
-typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
+using InvalidatedSymbols = llvm::DenseSet<SymbolRef>;
class StoreManager {
protected:
@@ -48,7 +63,7 @@ protected:
StoreManager(ProgramStateManager &stateMgr);
public:
- virtual ~StoreManager() {}
+ virtual ~StoreManager() = default;
/// Return the value bound to specified location in a given state.
/// \param[in] store The store in which to make the lookup.
@@ -92,9 +107,17 @@ public:
/// by \c val bound to the location given for \c loc.
virtual StoreRef Bind(Store store, Loc loc, SVal val) = 0;
- virtual StoreRef BindDefault(Store store, const MemRegion *R, SVal V);
+ /// Return a store with the specified value bound to all sub-regions of the
+ /// region. The region must not have previous bindings. If you need to
+ /// invalidate existing bindings, consider invalidateRegions().
+ virtual StoreRef BindDefaultInitial(Store store, const MemRegion *R,
+ SVal V) = 0;
- /// \brief Create a new store with the specified binding removed.
+ /// Return a store with in which all values within the given region are
+ /// reset to zero. This method is allowed to overwrite previous bindings.
+ virtual StoreRef BindDefaultZero(Store store, const MemRegion *R) = 0;
+
+ /// Create a new store with the specified binding removed.
/// \param ST the original store, that is the basis for the new store.
/// \param L the location whose binding should be removed.
virtual StoreRef killBinding(Store ST, Loc L) = 0;
@@ -147,7 +170,7 @@ public:
SVal evalDerivedToBase(SVal Derived, QualType DerivedPtrType,
bool IsVirtual);
- /// \brief Attempts to do a down cast. Used to model BaseToDerived and C++
+ /// Attempts to do a down cast. Used to model BaseToDerived and C++
/// dynamic_cast.
/// The callback may result in the following 3 scenarios:
/// - Successful cast (ex: derived is subclass of base).
@@ -168,7 +191,7 @@ public:
const MemRegion *castRegion(const MemRegion *region, QualType CastToTy);
virtual StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
- SymbolReaper& SymReaper) = 0;
+ SymbolReaper &SymReaper) = 0;
virtual bool includedInBindings(Store store,
const MemRegion *region) const = 0;
@@ -182,7 +205,7 @@ public:
/// associated with the object is recycled.
virtual void decrementReferenceCount(Store store) {}
- typedef SmallVector<const MemRegion *, 8> InvalidatedRegions;
+ using InvalidatedRegions = SmallVector<const MemRegion *, 8>;
/// invalidateRegions - Clears out the specified regions from the store,
/// marking their values as unknown. Depending on the store, this may also
@@ -235,6 +258,7 @@ public:
class BindingsHandler {
public:
virtual ~BindingsHandler();
+
virtual bool HandleBinding(StoreManager& SMgr, Store store,
const MemRegion *region, SVal val) = 0;
};
@@ -242,16 +266,16 @@ public:
class FindUniqueBinding :
public BindingsHandler {
SymbolRef Sym;
- const MemRegion* Binding;
- bool First;
+ const MemRegion* Binding = nullptr;
+ bool First = true;
public:
- FindUniqueBinding(SymbolRef sym)
- : Sym(sym), Binding(nullptr), First(true) {}
+ FindUniqueBinding(SymbolRef sym) : Sym(sym) {}
+
+ explicit operator bool() { return First && Binding; }
bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
SVal val) override;
- explicit operator bool() { return First && Binding; }
const MemRegion *getRegion() { return Binding; }
};
@@ -266,22 +290,21 @@ protected:
/// CastRetrievedVal - Used by subclasses of StoreManager to implement
/// implicit casts that arise from loads from regions that are reinterpreted
/// as another region.
- SVal CastRetrievedVal(SVal val, const TypedValueRegion *region,
- QualType castTy, bool performTestOnly = true);
+ SVal CastRetrievedVal(SVal val, const TypedValueRegion *region,
+ QualType castTy);
private:
SVal getLValueFieldOrIvar(const Decl *decl, SVal base);
};
-
inline StoreRef::StoreRef(Store store, StoreManager & smgr)
- : store(store), mgr(smgr) {
+ : store(store), mgr(smgr) {
if (store)
mgr.incrementReferenceCount(store);
}
-inline StoreRef::StoreRef(const StoreRef &sr)
- : store(sr.store), mgr(sr.mgr)
+inline StoreRef::StoreRef(const StoreRef &sr)
+ : store(sr.store), mgr(sr.mgr)
{
if (store)
mgr.incrementReferenceCount(store);
@@ -308,8 +331,8 @@ CreateRegionStoreManager(ProgramStateManager &StMgr);
std::unique_ptr<StoreManager>
CreateFieldsOnlyRegionStoreManager(ProgramStateManager &StMgr);
-} // end GR namespace
+} // namespace ento
-} // end clang namespace
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STORE_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
index 958c8c377ea2a..c5b4e5036bdf4 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
@@ -1,4 +1,4 @@
-//== StoreRef.h - Smart pointer for store objects ---------------*- C++ -*--==//
+//===- StoreRef.h - Smart pointer for store objects -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,33 +19,36 @@
namespace clang {
namespace ento {
+class StoreManager;
+
/// Store - This opaque type encapsulates an immutable mapping from
/// locations to values. At a high-level, it represents the symbolic
/// memory model. Different subclasses of StoreManager may choose
/// different types to represent the locations and values.
-typedef const void *Store;
-
-class StoreManager;
+using Store = const void *;
class StoreRef {
Store store;
StoreManager &mgr;
+
public:
- StoreRef(Store, StoreManager &);
- StoreRef(const StoreRef &);
- StoreRef &operator=(StoreRef const &);
+ StoreRef(Store store, StoreManager &smgr);
+ StoreRef(const StoreRef &sr);
+ StoreRef &operator=(StoreRef const &newStore);
+ ~StoreRef();
bool operator==(const StoreRef &x) const {
assert(&mgr == &x.mgr);
return x.store == store;
}
+
bool operator!=(const StoreRef &x) const { return !operator==(x); }
- ~StoreRef();
-
Store getStore() const { return store; }
const StoreManager &getStoreManager() const { return mgr; }
};
-}}
-#endif
+} // namespace ento
+} // namespace clang
+
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STOREREF_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index 8ccd34751bbe1..e574ffdd6a159 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -24,6 +24,10 @@ class CFGElement;
class LocationContext;
class Stmt;
+namespace cross_tu {
+class CrossTranslationUnitContext;
+}
+
namespace ento {
struct NodeBuilderContext;
@@ -49,6 +53,9 @@ public:
virtual AnalysisManager &getAnalysisManager() = 0;
+ virtual cross_tu::CrossTranslationUnitContext *
+ getCrossTranslationUnitContext() = 0;
+
virtual ProgramStateManager &getStateManager() = 0;
/// Called by CoreEngine. Used to generate new successor
@@ -155,7 +162,8 @@ public:
/// printState - Called by ProgramStateManager to print checker-specific data.
virtual void printState(raw_ostream &Out, ProgramStateRef State,
- const char *NL, const char *Sep) = 0;
+ const char *NL, const char *Sep,
+ const LocationContext *LCtx = nullptr) = 0;
/// Called by CoreEngine when the analysis worklist is either empty or the
// maximum number of analysis steps have been reached.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
index 9780d0144746e..69b9858d3feb7 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
@@ -1,4 +1,4 @@
-//== SymExpr.h - Management of Symbolic Values ------------------*- C++ -*--==//
+//===- SymExpr.h - Management of Symbolic Values ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,16 +15,17 @@
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMEXPR_H
#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/raw_ostream.h"
+#include <cassert>
namespace clang {
namespace ento {
class MemRegion;
-/// \brief Symbolic value. These values used to capture symbolic execution of
+/// Symbolic value. These values used to capture symbolic execution of
/// the program.
class SymExpr : public llvm::FoldingSetNode {
virtual void anchor();
@@ -48,8 +49,10 @@ protected:
return !T.isNull() && !T->isVoidType();
}
+ mutable unsigned Complexity = 0;
+
public:
- virtual ~SymExpr() {}
+ virtual ~SymExpr() = default;
Kind getKind() const { return K; }
@@ -60,17 +63,18 @@ public:
virtual QualType getType() const = 0;
virtual void Profile(llvm::FoldingSetNodeID &profile) = 0;
- /// \brief Iterator over symbols that the current symbol depends on.
+ /// Iterator over symbols that the current symbol depends on.
///
/// For SymbolData, it's the symbol itself; for expressions, it's the
/// expression symbol and all the operands in it. Note, SymbolDerived is
/// treated as SymbolData - the iterator will NOT visit the parent region.
class symbol_iterator {
SmallVector<const SymExpr *, 5> itr;
+
void expand();
public:
- symbol_iterator() {}
+ symbol_iterator() = default;
symbol_iterator(const SymExpr *SE);
symbol_iterator &operator++();
@@ -83,9 +87,9 @@ public:
symbol_iterator symbol_begin() const { return symbol_iterator(this); }
static symbol_iterator symbol_end() { return symbol_iterator(); }
- unsigned computeComplexity() const;
+ virtual unsigned computeComplexity() const = 0;
- /// \brief Find the region from which this symbol originates.
+ /// Find the region from which this symbol originates.
///
/// Whenever the symbol was constructed to denote an unknown value of
/// a certain memory region, return this region. This method
@@ -104,26 +108,31 @@ inline raw_ostream &operator<<(raw_ostream &os,
return os;
}
-typedef const SymExpr *SymbolRef;
-typedef SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy;
+using SymbolRef = const SymExpr *;
+using SymbolRefSmallVectorTy = SmallVector<SymbolRef, 2>;
+using SymbolID = unsigned;
-typedef unsigned SymbolID;
-/// \brief A symbol representing data which can be stored in a memory location
+/// A symbol representing data which can be stored in a memory location
/// (region).
class SymbolData : public SymExpr {
- void anchor() override;
const SymbolID Sym;
+ void anchor() override;
+
protected:
SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {
assert(classof(this));
}
public:
- ~SymbolData() override {}
+ ~SymbolData() override = default;
SymbolID getSymbolID() const { return Sym; }
+ unsigned computeComplexity() const override {
+ return 1;
+ };
+
// Implement isa<T> support.
static inline bool classof(const SymExpr *SE) {
Kind k = SE->getKind();
@@ -134,4 +143,4 @@ public:
} // namespace ento
} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMEXPR_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index 7d2e5ad8ba915..cc3ce72f9e569 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -1,4 +1,4 @@
-//== SymbolManager.h - Management of Symbolic Values ------------*- C++ -*--==//
+//===- SymbolManager.h - Management of Symbolic Values ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,8 +15,8 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMBOLMANAGER_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMBOLMANAGER_H
-#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
@@ -26,19 +26,19 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/DataTypes.h"
+#include <cassert>
namespace clang {
- class ASTContext;
- class StackFrameContext;
+
+class ASTContext;
+class Stmt;
namespace ento {
- class BasicValueFactory;
- class SubRegion;
- class TypedValueRegion;
- class VarRegion;
-///\brief A symbol representing the value stored at a MemRegion.
+class BasicValueFactory;
+class StoreManager;
+
+///A symbol representing the value stored at a MemRegion.
class SymbolRegionValue : public SymbolData {
const TypedValueRegion *R;
@@ -66,7 +66,7 @@ public:
QualType getType() const override;
// Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
+ static bool classof(const SymExpr *SE) {
return SE->getKind() == SymbolRegionValueKind;
}
};
@@ -118,7 +118,7 @@ public:
}
// Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
+ static bool classof(const SymExpr *SE) {
return SE->getKind() == SymbolConjuredKind;
}
};
@@ -157,7 +157,7 @@ public:
}
// Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
+ static bool classof(const SymExpr *SE) {
return SE->getKind() == SymbolDerivedKind;
}
};
@@ -190,7 +190,7 @@ public:
}
// Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
+ static bool classof(const SymExpr *SE) {
return SE->getKind() == SymbolExtentKind;
}
};
@@ -206,11 +206,12 @@ class SymbolMetadata : public SymbolData {
const LocationContext *LCtx;
unsigned Count;
const void *Tag;
+
public:
SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt *s, QualType t,
const LocationContext *LCtx, unsigned count, const void *tag)
- : SymbolData(SymbolMetadataKind, sym), R(r), S(s), T(t), LCtx(LCtx),
- Count(count), Tag(tag) {
+ : SymbolData(SymbolMetadataKind, sym), R(r), S(s), T(t), LCtx(LCtx),
+ Count(count), Tag(tag) {
assert(r);
assert(s);
assert(isValidTypeForSymbol(t));
@@ -245,16 +246,18 @@ public:
}
// Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
+ static bool classof(const SymExpr *SE) {
return SE->getKind() == SymbolMetadataKind;
}
};
-/// \brief Represents a cast expression.
+/// Represents a cast expression.
class SymbolCast : public SymExpr {
const SymExpr *Operand;
+
/// Type of the operand.
QualType FromTy;
+
/// The type of the result.
QualType ToTy;
@@ -267,6 +270,12 @@ public:
// Otherwise, 'To' should also be a valid type.
}
+ unsigned computeComplexity() const override {
+ if (Complexity == 0)
+ Complexity = 1 + Operand->computeComplexity();
+ return Complexity;
+ }
+
QualType getType() const override { return ToTy; }
const SymExpr *getOperand() const { return Operand; }
@@ -286,12 +295,12 @@ public:
}
// Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
+ static bool classof(const SymExpr *SE) {
return SE->getKind() == SymbolCastKind;
}
};
-/// \brief Represents a symbolic expression involving a binary operator
+/// Represents a symbolic expression involving a binary operator
class BinarySymExpr : public SymExpr {
BinaryOperator::Opcode Op;
QualType T;
@@ -311,13 +320,13 @@ public:
BinaryOperator::Opcode getOpcode() const { return Op; }
// Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
+ static bool classof(const SymExpr *SE) {
Kind k = SE->getKind();
return k >= BEGIN_BINARYSYMEXPRS && k <= END_BINARYSYMEXPRS;
}
};
-/// \brief Represents a symbolic expression like 'x' + 3.
+/// Represents a symbolic expression like 'x' + 3.
class SymIntExpr : public BinarySymExpr {
const SymExpr *LHS;
const llvm::APSInt& RHS;
@@ -334,6 +343,12 @@ public:
const SymExpr *getLHS() const { return LHS; }
const llvm::APSInt &getRHS() const { return RHS; }
+ unsigned computeComplexity() const override {
+ if (Complexity == 0)
+ Complexity = 1 + LHS->computeComplexity();
+ return Complexity;
+ }
+
static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
BinaryOperator::Opcode op, const llvm::APSInt& rhs,
QualType t) {
@@ -349,12 +364,12 @@ public:
}
// Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
+ static bool classof(const SymExpr *SE) {
return SE->getKind() == SymIntExprKind;
}
};
-/// \brief Represents a symbolic expression like 3 - 'x'.
+/// Represents a symbolic expression like 3 - 'x'.
class IntSymExpr : public BinarySymExpr {
const llvm::APSInt& LHS;
const SymExpr *RHS;
@@ -371,6 +386,12 @@ public:
const SymExpr *getRHS() const { return RHS; }
const llvm::APSInt &getLHS() const { return LHS; }
+ unsigned computeComplexity() const override {
+ if (Complexity == 0)
+ Complexity = 1 + RHS->computeComplexity();
+ return Complexity;
+ }
+
static void Profile(llvm::FoldingSetNodeID& ID, const llvm::APSInt& lhs,
BinaryOperator::Opcode op, const SymExpr *rhs,
QualType t) {
@@ -386,12 +407,12 @@ public:
}
// Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
+ static bool classof(const SymExpr *SE) {
return SE->getKind() == IntSymExprKind;
}
};
-/// \brief Represents a symbolic expression like 'x' + 'y'.
+/// Represents a symbolic expression like 'x' + 'y'.
class SymSymExpr : public BinarySymExpr {
const SymExpr *LHS;
const SymExpr *RHS;
@@ -409,6 +430,12 @@ public:
void dumpToStream(raw_ostream &os) const override;
+ unsigned computeComplexity() const override {
+ if (Complexity == 0)
+ Complexity = RHS->computeComplexity() + LHS->computeComplexity();
+ return Complexity;
+ }
+
static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) {
ID.AddInteger((unsigned) SymSymExprKind);
@@ -423,20 +450,22 @@ public:
}
// Implement isa<T> support.
- static inline bool classof(const SymExpr *SE) {
+ static bool classof(const SymExpr *SE) {
return SE->getKind() == SymSymExprKind;
}
};
class SymbolManager {
- typedef llvm::FoldingSet<SymExpr> DataSetTy;
- typedef llvm::DenseMap<SymbolRef, SymbolRefSmallVectorTy*> SymbolDependTy;
+ using DataSetTy = llvm::FoldingSet<SymExpr>;
+ using SymbolDependTy = llvm::DenseMap<SymbolRef, SymbolRefSmallVectorTy *>;
DataSetTy DataSet;
+
/// Stores the extra dependencies between symbols: the data should be kept
/// alive as long as the key is live.
SymbolDependTy SymbolDependencies;
- unsigned SymbolCounter;
+
+ unsigned SymbolCounter = 0;
llvm::BumpPtrAllocator& BPAlloc;
BasicValueFactory &BV;
ASTContext &Ctx;
@@ -444,14 +473,12 @@ class SymbolManager {
public:
SymbolManager(ASTContext &ctx, BasicValueFactory &bv,
llvm::BumpPtrAllocator& bpalloc)
- : SymbolDependencies(16), SymbolCounter(0),
- BPAlloc(bpalloc), BV(bv), Ctx(ctx) {}
-
+ : SymbolDependencies(16), BPAlloc(bpalloc), BV(bv), Ctx(ctx) {}
~SymbolManager();
static bool canSymbolicate(QualType T);
- /// \brief Make a unique symbol for MemRegion R according to its kind.
+ /// Make a unique symbol for MemRegion R according to its kind.
const SymbolRegionValue* getRegionValueSymbol(const TypedValueRegion* R);
const SymbolConjured* conjureSymbol(const Stmt *E,
@@ -472,7 +499,7 @@ public:
const SymbolExtent *getExtentSymbol(const SubRegion *R);
- /// \brief Creates a metadata symbol associated with a specific region.
+ /// Creates a metadata symbol associated with a specific region.
///
/// VisitCount can be used to differentiate regions corresponding to
/// different loop iterations, thus, making the symbol path-dependent.
@@ -504,7 +531,7 @@ public:
return SE->getType();
}
- /// \brief Add artificial symbol dependency.
+ /// Add artificial symbol dependency.
///
/// The dependent symbol should stay alive as long as the primary is alive.
void addSymbolDependency(const SymbolRef Primary, const SymbolRef Dependent);
@@ -515,16 +542,16 @@ public:
BasicValueFactory &getBasicVals() { return BV; }
};
-/// \brief A class responsible for cleaning up unused symbols.
+/// A class responsible for cleaning up unused symbols.
class SymbolReaper {
enum SymbolStatus {
NotProcessed,
HaveMarkedDependents
};
- typedef llvm::DenseSet<SymbolRef> SymbolSetTy;
- typedef llvm::DenseMap<SymbolRef, SymbolStatus> SymbolMapTy;
- typedef llvm::DenseSet<const MemRegion *> RegionSetTy;
+ using SymbolSetTy = llvm::DenseSet<SymbolRef>;
+ using SymbolMapTy = llvm::DenseMap<SymbolRef, SymbolStatus>;
+ using RegionSetTy = llvm::DenseSet<const MemRegion *>;
SymbolMapTy TheLiving;
SymbolSetTy MetadataInUse;
@@ -539,17 +566,16 @@ class SymbolReaper {
llvm::DenseMap<const MemRegion *, unsigned> includedRegionCache;
public:
- /// \brief Construct a reaper object, which removes everything which is not
+ /// Construct a reaper object, which removes everything which is not
/// live before we execute statement s in the given location context.
///
/// If the statement is NULL, everything is this and parent contexts is
/// considered live.
/// If the stack frame context is NULL, everything on stack is considered
/// dead.
- SymbolReaper(const StackFrameContext *Ctx, const Stmt *s, SymbolManager& symmgr,
- StoreManager &storeMgr)
- : LCtx(Ctx), Loc(s), SymMgr(symmgr),
- reapedStore(nullptr, storeMgr) {}
+ SymbolReaper(const StackFrameContext *Ctx, const Stmt *s,
+ SymbolManager &symmgr, StoreManager &storeMgr)
+ : LCtx(Ctx), Loc(s), SymMgr(symmgr), reapedStore(nullptr, storeMgr) {}
const LocationContext *getLocationContext() const { return LCtx; }
@@ -558,14 +584,14 @@ public:
bool isLive(const Stmt *ExprVal, const LocationContext *LCtx) const;
bool isLive(const VarRegion *VR, bool includeStoreBindings = false) const;
- /// \brief Unconditionally marks a symbol as live.
+ /// Unconditionally marks a symbol as live.
///
/// This should never be
/// used by checkers, only by the state infrastructure such as the store and
/// environment. Checkers should instead use metadata symbols and markInUse.
void markLive(SymbolRef sym);
- /// \brief Marks a symbol as important to a checker.
+ /// Marks a symbol as important to a checker.
///
/// For metadata symbols,
/// this will keep the symbol alive as long as its associated region is also
@@ -574,13 +600,14 @@ public:
/// symbol marking has occurred, i.e. in the MarkLiveSymbols callback.
void markInUse(SymbolRef sym);
- /// \brief If a symbol is known to be live, marks the symbol as live.
+ /// If a symbol is known to be live, marks the symbol as live.
///
/// Otherwise, if the symbol cannot be proven live, it is marked as dead.
/// Returns true if the symbol is dead, false if live.
bool maybeDead(SymbolRef sym);
- typedef SymbolSetTy::const_iterator dead_iterator;
+ using dead_iterator = SymbolSetTy::const_iterator;
+
dead_iterator dead_begin() const { return TheDead.begin(); }
dead_iterator dead_end() const { return TheDead.end(); }
@@ -588,11 +615,12 @@ public:
return !TheDead.empty();
}
- typedef RegionSetTy::const_iterator region_iterator;
+ using region_iterator = RegionSetTy::const_iterator;
+
region_iterator region_begin() const { return RegionRoots.begin(); }
region_iterator region_end() const { return RegionRoots.end(); }
- /// \brief Returns whether or not a symbol has been confirmed dead.
+ /// Returns whether or not a symbol has been confirmed dead.
///
/// This should only be called once all marking of dead symbols has completed.
/// (For checkers, this means only in the evalDeadSymbols callback.)
@@ -603,7 +631,7 @@ public:
void markLive(const MemRegion *region);
void markElementIndicesLive(const MemRegion *region);
- /// \brief Set to the value of the symbolic store after
+ /// Set to the value of the symbolic store after
/// StoreManager::removeDeadBindings has been called.
void setReapedStore(StoreRef st) { reapedStore = st; }
@@ -621,7 +649,7 @@ public:
SymbolVisitor(const SymbolVisitor &) = default;
SymbolVisitor(SymbolVisitor &&) {}
- /// \brief A visitor method invoked by ProgramStateManager::scanReachableSymbols.
+ /// A visitor method invoked by ProgramStateManager::scanReachableSymbols.
///
/// The method returns \c true if symbols should continue be scanned and \c
/// false otherwise.
@@ -629,8 +657,8 @@ public:
virtual bool VisitMemRegion(const MemRegion *region) { return true; }
};
-} // end GR namespace
+} // namespace ento
-} // end clang namespace
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMBOLMANAGER_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
index 7b76263f040c9..ce19b7131d42d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
@@ -1,4 +1,4 @@
-//== TaintManager.h - Managing taint --------------------------- -*- C++ -*--=//
+//===- TaintManager.h - Managing taint --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,9 +14,9 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTMANAGER_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTMANAGER_H
-#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
#include "llvm/ADT/ImmutableMap.h"
@@ -29,28 +29,37 @@ namespace ento {
// FIXME: This does not use the nice trait macros because it must be accessible
// from multiple translation units.
struct TaintMap {};
-typedef llvm::ImmutableMap<SymbolRef, TaintTagType> TaintMapImpl;
+
+using TaintMapImpl = llvm::ImmutableMap<SymbolRef, TaintTagType>;
+
template<> struct ProgramStateTrait<TaintMap>
: public ProgramStatePartialTrait<TaintMapImpl> {
- static void *GDMIndex() { static int index = 0; return &index; }
+ static void *GDMIndex() {
+ static int index = 0;
+ return &index;
+ }
};
/// The GDM component mapping derived symbols' parent symbols to their
/// underlying regions. This is used to efficiently check whether a symbol is
/// tainted when it represents a sub-region of a tainted symbol.
struct DerivedSymTaint {};
-typedef llvm::ImmutableMap<SymbolRef, TaintedSubRegions> DerivedSymTaintImpl;
+
+using DerivedSymTaintImpl = llvm::ImmutableMap<SymbolRef, TaintedSubRegions>;
+
template<> struct ProgramStateTrait<DerivedSymTaint>
: public ProgramStatePartialTrait<DerivedSymTaintImpl> {
- static void *GDMIndex() { static int index; return &index; }
+ static void *GDMIndex() {
+ static int index;
+ return &index;
+ }
};
class TaintManager {
-
- TaintManager() {}
+ TaintManager() = default;
};
-}
-}
+} // namespace ento
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTMANAGER_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
index 0c56e7d8ea698..50c4b8194cff8 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
@@ -1,4 +1,4 @@
-//== TaintTag.h - Path-sensitive "State" for tracking values -*- C++ -*--=//
+//===- TaintTag.h - Path-sensitive "State" for tracking values --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,6 +11,7 @@
// of taint.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H
@@ -19,9 +20,11 @@ namespace ento {
/// The type of taint, which helps to differentiate between different types of
/// taint.
-typedef unsigned TaintTagType;
+using TaintTagType = unsigned;
+
static const TaintTagType TaintTagGeneric = 0;
-}}
+} // namespace ento
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
index 4f1a60e675569..7df8f373b3663 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
@@ -80,20 +80,14 @@ public:
void setBlockCounter(BlockCounter C) { CurrentCounter = C; }
BlockCounter getBlockCounter() const { return CurrentCounter; }
- class Visitor {
- public:
- Visitor() {}
- virtual ~Visitor();
- virtual bool visit(const WorkListUnit &U) = 0;
- };
- virtual bool visitItemsInWorkList(Visitor &V) = 0;
-
- static WorkList *makeDFS();
- static WorkList *makeBFS();
- static WorkList *makeBFSBlockDFSContents();
+ static std::unique_ptr<WorkList> makeDFS();
+ static std::unique_ptr<WorkList> makeBFS();
+ static std::unique_ptr<WorkList> makeBFSBlockDFSContents();
+ static std::unique_ptr<WorkList> makeUnexploredFirst();
+ static std::unique_ptr<WorkList> makeUnexploredFirstPriorityQueue();
};
-} // end GR namespace
+} // end ento namespace
} // end clang namespace
diff --git a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
index a9dad6c5e9a29..59fbbc3ca80f9 100644
--- a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
+++ b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
@@ -17,6 +17,7 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/Basic/LLVM.h"
+#include <functional>
#include <memory>
namespace clang {
@@ -29,10 +30,24 @@ class CompilerInstance;
namespace ento {
class PathDiagnosticConsumer;
class CheckerManager;
+class CheckerRegistry;
class AnalysisASTConsumer : public ASTConsumer {
public:
virtual void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) = 0;
+
+ /// This method allows registering statically linked custom checkers that are
+ /// not a part of the Clang tree. It employs the same mechanism that is used
+ /// by plugins.
+ ///
+ /// Example:
+ ///
+ /// Consumer->AddCheckerRegistrationFn([] (CheckerRegistry& Registry) {
+ /// Registry.addChecker<MyCustomChecker>("example.MyCustomChecker",
+ /// "Description");
+ /// });
+ virtual void
+ AddCheckerRegistrationFn(std::function<void(CheckerRegistry &)> Fn) = 0;
};
/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
index 2985b7c117ef6..216a2359efba1 100644
--- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
+++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
@@ -11,6 +11,7 @@
#define LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H
#include "clang/Basic/LLVM.h"
+#include <functional>
#include <memory>
#include <string>
@@ -21,10 +22,13 @@ namespace clang {
namespace ento {
class CheckerManager;
+ class CheckerRegistry;
- std::unique_ptr<CheckerManager>
- createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts,
- ArrayRef<std::string> plugins, DiagnosticsEngine &diags);
+ std::unique_ptr<CheckerManager> createCheckerManager(
+ AnalyzerOptions &opts, const LangOptions &langOpts,
+ ArrayRef<std::string> plugins,
+ ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns,
+ DiagnosticsEngine &diags);
} // end ento namespace
diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
index e66d48b1be1dd..ba37b7f59a02d 100644
--- a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
+++ b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
@@ -31,7 +31,7 @@ protected:
StringRef InFile) override;
};
-/// \brief Frontend action to parse model files.
+/// Frontend action to parse model files.
///
/// This frontend action is responsible for parsing model files. Model files can
/// not be parsed on their own, they rely on type information that is available
diff --git a/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h b/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h
index 24f8042587f39..fa00ffd16553a 100644
--- a/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h
+++ b/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief This file implements clang::ento::ModelConsumer which is an
+/// This file implements clang::ento::ModelConsumer which is an
/// ASTConsumer for model files.
///
//===----------------------------------------------------------------------===//
@@ -25,7 +25,7 @@ class Stmt;
namespace ento {
-/// \brief ASTConsumer to consume model files' AST.
+/// ASTConsumer to consume model files' AST.
///
/// This consumer collects the bodies of function definitions into a StringMap
/// from a model file.
diff --git a/include/clang/Tooling/AllTUsExecution.h b/include/clang/Tooling/AllTUsExecution.h
new file mode 100644
index 0000000000000..f199365dc8153
--- /dev/null
+++ b/include/clang/Tooling/AllTUsExecution.h
@@ -0,0 +1,76 @@
+//===--- AllTUsExecution.h - Execute actions on all TUs. -*- 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 a tool executor that runs given actions on all TUs in the
+// compilation database. Tool results are deuplicated by the result key.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_ALLTUSEXECUTION_H
+#define LLVM_CLANG_TOOLING_ALLTUSEXECUTION_H
+
+#include "clang/Tooling/ArgumentsAdjusters.h"
+#include "clang/Tooling/Execution.h"
+
+namespace clang {
+namespace tooling {
+
+/// Executes given frontend actions on all files/TUs in the compilation
+/// database.
+class AllTUsToolExecutor : public ToolExecutor {
+public:
+ static const char *ExecutorName;
+
+ /// Init with \p CompilationDatabase.
+ /// This uses \p ThreadCount threads to exececute the actions on all files in
+ /// parallel. If \p ThreadCount is 0, this uses `llvm::hardware_concurrency`.
+ AllTUsToolExecutor(const CompilationDatabase &Compilations,
+ unsigned ThreadCount,
+ std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+ std::make_shared<PCHContainerOperations>());
+
+ /// Init with \p CommonOptionsParser. This is expected to be used by
+ /// `createExecutorFromCommandLineArgs` based on commandline options.
+ ///
+ /// The executor takes ownership of \p Options.
+ AllTUsToolExecutor(CommonOptionsParser Options, unsigned ThreadCount,
+ std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+ std::make_shared<PCHContainerOperations>());
+
+ StringRef getExecutorName() const override { return ExecutorName; }
+
+ using ToolExecutor::execute;
+
+ llvm::Error
+ execute(llvm::ArrayRef<
+ std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
+ Actions) override;
+
+ ExecutionContext *getExecutionContext() override { return &Context; };
+
+ ToolResults *getToolResults() override { return Results.get(); }
+
+ void mapVirtualFile(StringRef FilePath, StringRef Content) override {
+ OverlayFiles[FilePath] = Content;
+ }
+
+private:
+ // Used to store the parser when the executor is initialized with parser.
+ llvm::Optional<CommonOptionsParser> OptionsParser;
+ const CompilationDatabase &Compilations;
+ std::unique_ptr<ToolResults> Results;
+ ExecutionContext Context;
+ llvm::StringMap<std::string> OverlayFiles;
+ unsigned ThreadCount;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_ALLTUSEXECUTION_H
diff --git a/include/clang/Tooling/ArgumentsAdjusters.h b/include/clang/Tooling/ArgumentsAdjusters.h
index 4eb02251a7758..94ccf1f34e576 100644
--- a/include/clang/Tooling/ArgumentsAdjusters.h
+++ b/include/clang/Tooling/ArgumentsAdjusters.h
@@ -1,4 +1,4 @@
-//===--- ArgumentsAdjusters.h - Command line arguments adjuster -*- C++ -*-===//
+//===- ArgumentsAdjusters.h - Command line arguments adjuster ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares typedef ArgumentsAdjuster and functions to create several
+// This file declares type ArgumentsAdjuster and functions to create several
// useful argument adjusters.
// ArgumentsAdjusters modify command line arguments obtained from a compilation
// database before they are used to run a frontend action.
@@ -26,42 +26,42 @@
namespace clang {
namespace tooling {
-/// \brief A sequence of command line arguments.
-typedef std::vector<std::string> CommandLineArguments;
+/// A sequence of command line arguments.
+using CommandLineArguments = std::vector<std::string>;
-/// \brief A prototype of a command line adjuster.
+/// A prototype of a command line adjuster.
///
/// Command line argument adjuster is responsible for command line arguments
/// modification before the arguments are used to run a frontend action.
-typedef std::function<CommandLineArguments(
- const CommandLineArguments &, StringRef Filename)> ArgumentsAdjuster;
+using ArgumentsAdjuster = std::function<CommandLineArguments(
+ const CommandLineArguments &, StringRef Filename)>;
-/// \brief Gets an argument adjuster that converts input command line arguments
+/// Gets an argument adjuster that converts input command line arguments
/// to the "syntax check only" variant.
ArgumentsAdjuster getClangSyntaxOnlyAdjuster();
-/// \brief Gets an argument adjuster which removes output-related command line
+/// Gets an argument adjuster which removes output-related command line
/// arguments.
ArgumentsAdjuster getClangStripOutputAdjuster();
-/// \brief Gets an argument adjuster which removes dependency-file
+/// Gets an argument adjuster which removes dependency-file
/// related command line arguments.
ArgumentsAdjuster getClangStripDependencyFileAdjuster();
enum class ArgumentInsertPosition { BEGIN, END };
-/// \brief Gets an argument adjuster which inserts \p Extra arguments in the
+/// Gets an argument adjuster which inserts \p Extra arguments in the
/// specified position.
ArgumentsAdjuster getInsertArgumentAdjuster(const CommandLineArguments &Extra,
ArgumentInsertPosition Pos);
-/// \brief Gets an argument adjuster which inserts an \p Extra argument in the
+/// Gets an argument adjuster which inserts an \p Extra argument in the
/// specified position.
ArgumentsAdjuster getInsertArgumentAdjuster(
const char *Extra,
ArgumentInsertPosition Pos = ArgumentInsertPosition::END);
-/// \brief Gets an argument adjuster which adjusts the arguments in sequence
+/// Gets an argument adjuster which adjusts the arguments in sequence
/// with the \p First adjuster and then with the \p Second one.
ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First,
ArgumentsAdjuster Second);
@@ -70,4 +70,3 @@ ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First,
} // namespace clang
#endif // LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H
-
diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h
index 15e8161dd76fb..7aaa712f9bafb 100644
--- a/include/clang/Tooling/CommonOptionsParser.h
+++ b/include/clang/Tooling/CommonOptionsParser.h
@@ -34,7 +34,7 @@
namespace clang {
namespace tooling {
-/// \brief A parser for options common to all command-line Clang tools.
+/// A parser for options common to all command-line Clang tools.
///
/// Parses a common subset of command-line arguments, locates and loads a
/// compilation commands database and runs a tool with user-specified action. It
@@ -52,7 +52,7 @@ namespace tooling {
///
/// static cl::OptionCategory MyToolCategory("My tool options");
/// static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
-/// static cl::extrahelp MoreHelp("\nMore help text...");
+/// static cl::extrahelp MoreHelp("\nMore help text...\n");
/// static cl::opt<bool> YourOwnOption(...);
/// ...
///
@@ -65,7 +65,7 @@ namespace tooling {
/// \endcode
class CommonOptionsParser {
public:
- /// \brief Parses command-line, initializes a compilation database.
+ /// Parses command-line, initializes a compilation database.
///
/// This constructor can change argc and argv contents, e.g. consume
/// command-line options used for creating FixedCompilationDatabase.
@@ -79,7 +79,7 @@ public:
: CommonOptionsParser(argc, argv, Category, llvm::cl::OneOrMore,
Overview) {}
- /// \brief Parses command-line, initializes a compilation database.
+ /// Parses command-line, initializes a compilation database.
///
/// This constructor can change argc and argv contents, e.g. consume
/// command-line options used for creating FixedCompilationDatabase.
@@ -92,7 +92,7 @@ public:
llvm::cl::NumOccurrencesFlag OccurrencesFlag,
const char *Overview = nullptr);
- /// \brief A factory method that is similar to the above constructor, except
+ /// A factory method that is similar to the above constructor, except
/// this returns an error instead exiting the program on error.
static llvm::Expected<CommonOptionsParser>
create(int &argc, const char **argv, llvm::cl::OptionCategory &Category,
diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h
index bc3e67b77de25..37e515fdc09e4 100644
--- a/include/clang/Tooling/CompilationDatabase.h
+++ b/include/clang/Tooling/CompilationDatabase.h
@@ -1,4 +1,4 @@
-//===--- CompilationDatabase.h - --------------------------------*- C++ -*-===//
+//===- CompilationDatabase.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -34,35 +34,43 @@
#include "llvm/ADT/Twine.h"
#include <memory>
#include <string>
+#include <utility>
#include <vector>
namespace clang {
namespace tooling {
-/// \brief Specifies the working directory and command of a compilation.
+/// Specifies the working directory and command of a compilation.
struct CompileCommand {
- CompileCommand() {}
+ CompileCommand() = default;
CompileCommand(Twine Directory, Twine Filename,
std::vector<std::string> CommandLine, Twine Output)
- : Directory(Directory.str()),
- Filename(Filename.str()),
- CommandLine(std::move(CommandLine)),
- Output(Output.str()){}
+ : Directory(Directory.str()), Filename(Filename.str()),
+ CommandLine(std::move(CommandLine)), Output(Output.str()){}
- /// \brief The working directory the command was executed from.
+ /// The working directory the command was executed from.
std::string Directory;
/// The source file associated with the command.
std::string Filename;
- /// \brief The command line that was executed.
+ /// The command line that was executed.
std::vector<std::string> CommandLine;
/// The output file associated with the command.
std::string Output;
+
+ friend bool operator==(const CompileCommand &LHS, const CompileCommand &RHS) {
+ return LHS.Directory == RHS.Directory && LHS.Filename == RHS.Filename &&
+ LHS.CommandLine == RHS.CommandLine && LHS.Output == RHS.Output;
+ }
+
+ friend bool operator!=(const CompileCommand &LHS, const CompileCommand &RHS) {
+ return !(LHS == RHS);
+ }
};
-/// \brief Interface for compilation databases.
+/// Interface for compilation databases.
///
/// A compilation database allows the user to retrieve compile command lines
/// for the files in a project.
@@ -74,7 +82,7 @@ class CompilationDatabase {
public:
virtual ~CompilationDatabase();
- /// \brief Loads a compilation database from a build directory.
+ /// Loads a compilation database from a build directory.
///
/// Looks at the specified 'BuildDirectory' and creates a compilation database
/// that allows to query compile commands for source files in the
@@ -89,21 +97,21 @@ public:
static std::unique_ptr<CompilationDatabase>
loadFromDirectory(StringRef BuildDirectory, std::string &ErrorMessage);
- /// \brief Tries to detect a compilation database location and load it.
+ /// Tries to detect a compilation database location and load it.
///
/// Looks for a compilation database in all parent paths of file 'SourceFile'
/// by calling loadFromDirectory.
static std::unique_ptr<CompilationDatabase>
autoDetectFromSource(StringRef SourceFile, std::string &ErrorMessage);
- /// \brief Tries to detect a compilation database location and load it.
+ /// Tries to detect a compilation database location and load it.
///
/// Looks for a compilation database in directory 'SourceDir' and all
/// its parent paths by calling loadFromDirectory.
static std::unique_ptr<CompilationDatabase>
autoDetectFromDirectory(StringRef SourceDir, std::string &ErrorMessage);
- /// \brief Returns all compile commands in which the specified file was
+ /// Returns all compile commands in which the specified file was
/// compiled.
///
/// This includes compile commands that span multiple source files.
@@ -113,15 +121,15 @@ public:
/// A compilation database representing the project would return both command
/// lines for a.cc and b.cc and only the first command line for t.cc.
virtual std::vector<CompileCommand> getCompileCommands(
- StringRef FilePath) const = 0;
+ StringRef FilePath) const = 0;
- /// \brief Returns the list of all files available in the compilation database.
+ /// Returns the list of all files available in the compilation database.
///
/// By default, returns nothing. Implementations should override this if they
/// can enumerate their source files.
virtual std::vector<std::string> getAllFiles() const { return {}; }
- /// \brief Returns all compile commands for all the files in the compilation
+ /// Returns all compile commands for all the files in the compilation
/// database.
///
/// FIXME: Add a layer in Tooling that provides an interface to run a tool
@@ -133,7 +141,7 @@ public:
virtual std::vector<CompileCommand> getAllCompileCommands() const;
};
-/// \brief Interface for compilation database plugins.
+/// Interface for compilation database plugins.
///
/// A compilation database plugin allows the user to register custom compilation
/// databases that are picked up as compilation database if the corresponding
@@ -147,20 +155,20 @@ class CompilationDatabasePlugin {
public:
virtual ~CompilationDatabasePlugin();
- /// \brief Loads a compilation database from a build directory.
+ /// Loads a compilation database from a build directory.
///
/// \see CompilationDatabase::loadFromDirectory().
virtual std::unique_ptr<CompilationDatabase>
loadFromDirectory(StringRef Directory, std::string &ErrorMessage) = 0;
};
-/// \brief A compilation database that returns a single compile command line.
+/// A compilation database that returns a single compile command line.
///
/// Useful when we want a tool to behave more like a compiler invocation.
/// This compilation database is not enumerable: getAllFiles() returns {}.
class FixedCompilationDatabase : public CompilationDatabase {
public:
- /// \brief Creates a FixedCompilationDatabase from the arguments after "--".
+ /// Creates a FixedCompilationDatabase from the arguments after "--".
///
/// Parses the given command line for "--". If "--" is found, the rest of
/// the arguments will make up the command line in the returned
@@ -196,11 +204,11 @@ public:
static std::unique_ptr<FixedCompilationDatabase>
loadFromFile(StringRef Path, std::string &ErrorMsg);
- /// \brief Constructs a compilation data base from a specified directory
+ /// Constructs a compilation data base from a specified directory
/// and command line.
FixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine);
- /// \brief Returns the given compile command.
+ /// Returns the given compile command.
///
/// Will always return a vector with one entry that contains the directory
/// and command line specified at construction with "clang-tool" as argv[0]
@@ -214,7 +222,14 @@ private:
std::vector<CompileCommand> CompileCommands;
};
-} // end namespace tooling
-} // end namespace clang
+/// Returns a wrapped CompilationDatabase that defers to the provided one,
+/// but getCompileCommands() will infer commands for unknown files.
+/// The return value of getAllFiles() or getAllCompileCommands() is unchanged.
+/// See InterpolatingCompilationDatabase.cpp for details on heuristics.
+std::unique_ptr<CompilationDatabase>
+ inferMissingCompileCommands(std::unique_ptr<CompilationDatabase>);
+
+} // namespace tooling
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H
diff --git a/include/clang/Tooling/CompilationDatabasePluginRegistry.h b/include/clang/Tooling/CompilationDatabasePluginRegistry.h
index 7323ec8974036..051a08e2a91e8 100644
--- a/include/clang/Tooling/CompilationDatabasePluginRegistry.h
+++ b/include/clang/Tooling/CompilationDatabasePluginRegistry.h
@@ -1,4 +1,4 @@
-//===--- CompilationDatabasePluginRegistry.h - ------------------*- C++ -*-===//
+//===- CompilationDatabasePluginRegistry.h ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,12 +16,10 @@
namespace clang {
namespace tooling {
-class CompilationDatabasePlugin;
+using CompilationDatabasePluginRegistry =
+ llvm::Registry<CompilationDatabasePlugin>;
-typedef llvm::Registry<CompilationDatabasePlugin>
- CompilationDatabasePluginRegistry;
+} // namespace tooling
+} // namespace clang
-} // end namespace tooling
-} // end namespace clang
-
-#endif
+#endif // LLVM_CLANG_TOOLING_COMPILATIONDATABASEPLUGINREGISTRY_H
diff --git a/include/clang/Tooling/Core/Diagnostic.h b/include/clang/Tooling/Core/Diagnostic.h
index b4920d4fe456d..ddb40103e2119 100644
--- a/include/clang/Tooling/Core/Diagnostic.h
+++ b/include/clang/Tooling/Core/Diagnostic.h
@@ -27,13 +27,13 @@
namespace clang {
namespace tooling {
-/// \brief Represents the diagnostic message with the error message associated
+/// Represents the diagnostic message with the error message associated
/// and the information on the location of the problem.
struct DiagnosticMessage {
DiagnosticMessage(llvm::StringRef Message = "");
- /// \brief Constructs a diagnostic message with anoffset to the diagnostic
- /// within the file where the problem occured.
+ /// Constructs a diagnostic message with anoffset to the diagnostic
+ /// within the file where the problem occurred.
///
/// \param Loc Should be a file location, it is not meaningful for a macro
/// location.
@@ -45,7 +45,7 @@ struct DiagnosticMessage {
unsigned FileOffset;
};
-/// \brief Represents the diagnostic with the level of severity and possible
+/// Represents the diagnostic with the level of severity and possible
/// fixes to be applied.
struct Diagnostic {
enum Level {
@@ -63,22 +63,22 @@ struct Diagnostic {
const SmallVector<DiagnosticMessage, 1> &Notes, Level DiagLevel,
llvm::StringRef BuildDirectory);
- /// \brief Name identifying the Diagnostic.
+ /// Name identifying the Diagnostic.
std::string DiagnosticName;
- /// \brief Message associated to the diagnostic.
+ /// Message associated to the diagnostic.
DiagnosticMessage Message;
- /// \brief Fixes to apply, grouped by file path.
+ /// Fixes to apply, grouped by file path.
llvm::StringMap<Replacements> Fix;
- /// \brief Potential notes about the diagnostic.
+ /// Potential notes about the diagnostic.
SmallVector<DiagnosticMessage, 1> Notes;
- /// \brief Diagnostic level. Can indicate either an error or a warning.
+ /// Diagnostic level. Can indicate either an error or a warning.
Level DiagLevel;
- /// \brief A build directory of the diagnostic source file.
+ /// A build directory of the diagnostic source file.
///
/// It's an absolute path which is `directory` field of the source file in
/// compilation database. If users don't specify the compilation database
@@ -88,7 +88,7 @@ struct Diagnostic {
std::string BuildDirectory;
};
-/// \brief Collection of Diagnostics generated from a single translation unit.
+/// Collection of Diagnostics generated from a single translation unit.
struct TranslationUnitDiagnostics {
/// Name of the main source for the translation unit.
std::string MainSourceFile;
diff --git a/include/clang/Tooling/Core/Replacement.h b/include/clang/Tooling/Core/Replacement.h
index 3fea9aee604ca..ba11ca4a7fee2 100644
--- a/include/clang/Tooling/Core/Replacement.h
+++ b/include/clang/Tooling/Core/Replacement.h
@@ -1,4 +1,4 @@
-//===--- Replacement.h - Framework for clang refactoring tools --*- C++ -*-===//
+//===- Replacement.h - Framework for clang refactoring tools ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,32 +19,35 @@
#ifndef LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
#define LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
-#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <set>
#include <string>
#include <system_error>
+#include <utility>
#include <vector>
namespace clang {
+class FileManager;
class Rewriter;
+class SourceManager;
namespace tooling {
-/// \brief A source range independent of the \c SourceManager.
+/// A source range independent of the \c SourceManager.
class Range {
public:
- Range() : Offset(0), Length(0) {}
+ Range() = default;
Range(unsigned Offset, unsigned Length) : Offset(Offset), Length(Length) {}
- /// \brief Accessors.
+ /// Accessors.
/// @{
unsigned getOffset() const { return Offset; }
unsigned getLength() const { return Length; }
@@ -52,38 +55,38 @@ public:
/// \name Range Predicates
/// @{
- /// \brief Whether this range overlaps with \p RHS or not.
+ /// Whether this range overlaps with \p RHS or not.
bool overlapsWith(Range RHS) const {
return Offset + Length > RHS.Offset && Offset < RHS.Offset + RHS.Length;
}
- /// \brief Whether this range contains \p RHS or not.
+ /// Whether this range contains \p RHS or not.
bool contains(Range RHS) const {
return RHS.Offset >= Offset &&
(RHS.Offset + RHS.Length) <= (Offset + Length);
}
- /// \brief Whether this range equals to \p RHS or not.
+ /// Whether this range equals to \p RHS or not.
bool operator==(const Range &RHS) const {
return Offset == RHS.getOffset() && Length == RHS.getLength();
}
/// @}
private:
- unsigned Offset;
- unsigned Length;
+ unsigned Offset = 0;
+ unsigned Length = 0;
};
-/// \brief A text replacement.
+/// A text replacement.
///
/// Represents a SourceManager independent replacement of a range of text in a
/// specific file.
class Replacement {
public:
- /// \brief Creates an invalid (not applicable) replacement.
+ /// Creates an invalid (not applicable) replacement.
Replacement();
- /// \brief Creates a replacement of the range [Offset, Offset+Length) in
+ /// Creates a replacement of the range [Offset, Offset+Length) in
/// FilePath with ReplacementText.
///
/// \param FilePath A source file accessible via a SourceManager.
@@ -92,28 +95,28 @@ public:
Replacement(StringRef FilePath, unsigned Offset, unsigned Length,
StringRef ReplacementText);
- /// \brief Creates a Replacement of the range [Start, Start+Length) with
+ /// Creates a Replacement of the range [Start, Start+Length) with
/// ReplacementText.
Replacement(const SourceManager &Sources, SourceLocation Start,
unsigned Length, StringRef ReplacementText);
- /// \brief Creates a Replacement of the given range with ReplacementText.
+ /// Creates a Replacement of the given range with ReplacementText.
Replacement(const SourceManager &Sources, const CharSourceRange &Range,
StringRef ReplacementText,
const LangOptions &LangOpts = LangOptions());
- /// \brief Creates a Replacement of the node with ReplacementText.
+ /// Creates a Replacement of the node with ReplacementText.
template <typename Node>
Replacement(const SourceManager &Sources, const Node &NodeToReplace,
StringRef ReplacementText,
const LangOptions &LangOpts = LangOptions());
- /// \brief Returns whether this replacement can be applied to a file.
+ /// Returns whether this replacement can be applied to a file.
///
/// Only replacements that are in a valid file can be applied.
bool isApplicable() const;
- /// \brief Accessors.
+ /// Accessors.
/// @{
StringRef getFilePath() const { return FilePath; }
unsigned getOffset() const { return ReplacementRange.getOffset(); }
@@ -121,10 +124,10 @@ public:
StringRef getReplacementText() const { return ReplacementText; }
/// @}
- /// \brief Applies the replacement on the Rewriter.
+ /// Applies the replacement on the Rewriter.
bool apply(Rewriter &Rewrite) const;
- /// \brief Returns a human readable string representation.
+ /// Returns a human readable string representation.
std::string toString() const;
private:
@@ -147,17 +150,17 @@ enum class replacement_error {
insert_conflict,
};
-/// \brief Carries extra error information in replacement-related llvm::Error,
+/// Carries extra error information in replacement-related llvm::Error,
/// e.g. fail applying replacements and replacements conflict.
class ReplacementError : public llvm::ErrorInfo<ReplacementError> {
public:
ReplacementError(replacement_error Err) : Err(Err) {}
- /// \brief Constructs an error related to an existing replacement.
+ /// Constructs an error related to an existing replacement.
ReplacementError(replacement_error Err, Replacement Existing)
: Err(Err), ExistingReplacement(std::move(Existing)) {}
- /// \brief Constructs an error related to a new replacement and an existing
+ /// Constructs an error related to a new replacement and an existing
/// replacement in a set of replacements.
ReplacementError(replacement_error Err, Replacement New, Replacement Existing)
: Err(Err), NewReplacement(std::move(New)),
@@ -186,35 +189,37 @@ private:
}
replacement_error Err;
+
// A new replacement, which is to expected be added into a set of
// replacements, that is causing problem.
llvm::Optional<Replacement> NewReplacement;
+
// An existing replacement in a replacements set that is causing problem.
llvm::Optional<Replacement> ExistingReplacement;
};
-/// \brief Less-than operator between two Replacements.
+/// Less-than operator between two Replacements.
bool operator<(const Replacement &LHS, const Replacement &RHS);
-/// \brief Equal-to operator between two Replacements.
+/// Equal-to operator between two Replacements.
bool operator==(const Replacement &LHS, const Replacement &RHS);
-/// \brief Maintains a set of replacements that are conflict-free.
+/// Maintains a set of replacements that are conflict-free.
/// Two replacements are considered conflicts if they overlap or have the same
/// offset (i.e. order-dependent).
class Replacements {
- private:
- typedef std::set<Replacement> ReplacementsImpl;
+private:
+ using ReplacementsImpl = std::set<Replacement>;
- public:
- typedef ReplacementsImpl::const_iterator const_iterator;
- typedef ReplacementsImpl::const_reverse_iterator const_reverse_iterator;
+public:
+ using const_iterator = ReplacementsImpl::const_iterator;
+ using const_reverse_iterator = ReplacementsImpl::const_reverse_iterator;
Replacements() = default;
explicit Replacements(const Replacement &R) { Replaces.insert(R); }
- /// \brief Adds a new replacement \p R to the current set of replacements.
+ /// Adds a new replacement \p R to the current set of replacements.
/// \p R must have the same file path as all existing replacements.
/// Returns `success` if the replacement is successfully inserted; otherwise,
/// it returns an llvm::Error, i.e. there is a conflict between R and the
@@ -253,7 +258,7 @@ class Replacements {
/// category of replacements.
llvm::Error add(const Replacement &R);
- /// \brief Merges \p Replaces into the current replacements. \p Replaces
+ /// Merges \p Replaces into the current replacements. \p Replaces
/// refers to code after applying the current replacements.
LLVM_NODISCARD Replacements merge(const Replacements &Replaces) const;
@@ -283,7 +288,6 @@ class Replacements {
return Replaces == RHS.Replaces;
}
-
private:
Replacements(const_iterator Begin, const_iterator End)
: Replaces(Begin, End) {}
@@ -307,7 +311,7 @@ private:
ReplacementsImpl Replaces;
};
-/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
+/// Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
///
/// Replacement applications happen independently of the success of
/// other applications.
@@ -315,7 +319,7 @@ private:
/// \returns true if all replacements apply. false otherwise.
bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
-/// \brief Applies all replacements in \p Replaces to \p Code.
+/// Applies all replacements in \p Replaces to \p Code.
///
/// This completely ignores the path stored in each replacement. If all
/// replacements are applied successfully, this returns the code with
@@ -325,14 +329,15 @@ bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
llvm::Expected<std::string> applyAllReplacements(StringRef Code,
const Replacements &Replaces);
-/// \brief Collection of Replacements generated from a single translation unit.
+/// Collection of Replacements generated from a single translation unit.
struct TranslationUnitReplacements {
/// Name of the main source for the translation unit.
std::string MainSourceFile;
+
std::vector<Replacement> Replacements;
};
-/// \brief Calculates the new ranges after \p Replaces are applied. These
+/// Calculates the new ranges after \p Replaces are applied. These
/// include both the original \p Ranges and the affected ranges of \p Replaces
/// in the new code.
///
@@ -344,7 +349,7 @@ std::vector<Range>
calculateRangesAfterReplacements(const Replacements &Replaces,
const std::vector<Range> &Ranges);
-/// \brief If there are multiple <File, Replacements> pairs with the same file
+/// If there are multiple <File, Replacements> pairs with the same file
/// entry, we only keep one pair and discard the rest.
/// If a file does not exist, its corresponding replacements will be ignored.
std::map<std::string, Replacements> groupReplacementsByFile(
@@ -360,7 +365,8 @@ Replacement::Replacement(const SourceManager &Sources,
setFromSourceRange(Sources, Range, ReplacementText, LangOpts);
}
-} // end namespace tooling
-} // end namespace clang
+} // namespace tooling
+
+} // namespace clang
#endif // LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
diff --git a/include/clang/Tooling/DiagnosticsYaml.h b/include/clang/Tooling/DiagnosticsYaml.h
index 4d6ff063641b9..bf0732bf0042e 100644
--- a/include/clang/Tooling/DiagnosticsYaml.h
+++ b/include/clang/Tooling/DiagnosticsYaml.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief This file defines the structure of a YAML document for serializing
+/// This file defines the structure of a YAML document for serializing
/// diagnostics.
///
//===----------------------------------------------------------------------===//
@@ -27,7 +27,7 @@ namespace llvm {
namespace yaml {
template <> struct MappingTraits<clang::tooling::Diagnostic> {
- /// \brief Helper to (de)serialize a Diagnostic since we don't have direct
+ /// Helper to (de)serialize a Diagnostic since we don't have direct
/// access to its data members.
class NormalizedDiagnostic {
public:
@@ -80,7 +80,7 @@ template <> struct MappingTraits<clang::tooling::Diagnostic> {
}
};
-/// \brief Specialized MappingTraits to describe how a
+/// Specialized MappingTraits to describe how a
/// TranslationUnitDiagnostics is (de)serialized.
template <> struct MappingTraits<clang::tooling::TranslationUnitDiagnostics> {
static void mapping(IO &Io, clang::tooling::TranslationUnitDiagnostics &Doc) {
diff --git a/include/clang/Tooling/Execution.h b/include/clang/Tooling/Execution.h
index 1a44c4788c492..68aef53cb58f3 100644
--- a/include/clang/Tooling/Execution.h
+++ b/include/clang/Tooling/Execution.h
@@ -32,11 +32,12 @@
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Registry.h"
+#include "llvm/Support/StringSaver.h"
namespace clang {
namespace tooling {
-/// \brief An abstraction for the result of a tool execution. For example, the
+/// An abstraction for the result of a tool execution. For example, the
/// underlying result can be in-memory or on-disk.
///
/// Results should be string key-value pairs. For example, a refactoring tool
@@ -45,32 +46,41 @@ class ToolResults {
public:
virtual ~ToolResults() = default;
virtual void addResult(StringRef Key, StringRef Value) = 0;
- virtual std::vector<std::pair<std::string, std::string>> AllKVResults() = 0;
+ virtual std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
+ AllKVResults() = 0;
virtual void forEachResult(
llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) = 0;
};
+/// Stores the key-value results in memory. It maintains the lifetime of
+/// the result. Clang tools using this class are expected to generate a small
+/// set of different results, or a large set of duplicated results.
class InMemoryToolResults : public ToolResults {
public:
+ InMemoryToolResults() : Strings(Arena) {}
void addResult(StringRef Key, StringRef Value) override;
- std::vector<std::pair<std::string, std::string>> AllKVResults() override;
+ std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
+ AllKVResults() override;
void forEachResult(llvm::function_ref<void(StringRef Key, StringRef Value)>
Callback) override;
private:
- std::vector<std::pair<std::string, std::string>> KVResults;
+ llvm::BumpPtrAllocator Arena;
+ llvm::UniqueStringSaver Strings;
+
+ std::vector<std::pair<llvm::StringRef, llvm::StringRef>> KVResults;
};
-/// \brief The context of an execution, including the information about
+/// The context of an execution, including the information about
/// compilation and results.
class ExecutionContext {
public:
virtual ~ExecutionContext() {}
- /// \brief Initializes a context. This does not take ownership of `Results`.
+ /// Initializes a context. This does not take ownership of `Results`.
explicit ExecutionContext(ToolResults *Results) : Results(Results) {}
- /// \brief Adds a KV pair to the result container of this execution.
+ /// Adds a KV pair to the result container of this execution.
void reportResult(StringRef Key, StringRef Value);
// Returns the source control system's revision number if applicable.
@@ -88,7 +98,7 @@ private:
ToolResults *Results;
};
-/// \brief Interface for executing clang frontend actions.
+/// Interface for executing clang frontend actions.
///
/// This can be extended to support running tool actions in different
/// execution mode, e.g. on a specific set of TUs or many TUs in parallel.
@@ -101,54 +111,54 @@ class ToolExecutor {
public:
virtual ~ToolExecutor() {}
- /// \brief Returns the name of a specific executor.
+ /// Returns the name of a specific executor.
virtual StringRef getExecutorName() const = 0;
- /// \brief Executes each action with a corresponding arguments adjuster.
+ /// Executes each action with a corresponding arguments adjuster.
virtual llvm::Error
execute(llvm::ArrayRef<
std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
Actions) = 0;
- /// \brief Convenient functions for the above `execute`.
+ /// Convenient functions for the above `execute`.
llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action);
/// Executes an action with an argument adjuster.
llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action,
ArgumentsAdjuster Adjuster);
- /// \brief Returns a reference to the execution context.
+ /// Returns a reference to the execution context.
///
/// This should be passed to tool callbacks, and tool callbacks should report
/// results via the returned context.
virtual ExecutionContext *getExecutionContext() = 0;
- /// \brief Returns a reference to the result container.
+ /// Returns a reference to the result container.
///
/// NOTE: This should only be used after the execution finishes. Tool
/// callbacks should report results via `ExecutionContext` instead.
virtual ToolResults *getToolResults() = 0;
- /// \brief Map a virtual file to be used while running the tool.
+ /// Map a virtual file to be used while running the tool.
///
/// \param FilePath The path at which the content will be mapped.
/// \param Content A buffer of the file's content.
virtual void mapVirtualFile(StringRef FilePath, StringRef Content) = 0;
};
-/// \brief Interface for factories that create specific executors. This is also
+/// Interface for factories that create specific executors. This is also
/// used as a plugin to be registered into ToolExecutorPluginRegistry.
class ToolExecutorPlugin {
public:
virtual ~ToolExecutorPlugin() {}
- /// \brief Create an `ToolExecutor`.
+ /// Create an `ToolExecutor`.
///
/// `OptionsParser` can be consumed (e.g. moved) if the creation succeeds.
virtual llvm::Expected<std::unique_ptr<ToolExecutor>>
create(CommonOptionsParser &OptionsParser) = 0;
};
-/// \brief This creates a ToolExecutor that is in the global registry based on
+/// This creates a ToolExecutor that is in the global registry based on
/// commandline arguments.
///
/// This picks the right executor based on the `--executor` option. This parses
diff --git a/include/clang/Tooling/FileMatchTrie.h b/include/clang/Tooling/FileMatchTrie.h
index 882979ef8ff64..11d12f3d30ce0 100644
--- a/include/clang/Tooling/FileMatchTrie.h
+++ b/include/clang/Tooling/FileMatchTrie.h
@@ -1,4 +1,4 @@
-//===--- FileMatchTrie.h - --------------------------------------*- C++ -*-===//
+//===- FileMatchTrie.h ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,22 +16,21 @@
#define LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
#include <memory>
-namespace llvm {
-class StringRef;
-}
-
namespace clang {
namespace tooling {
+class FileMatchTrieNode;
+
struct PathComparator {
- virtual ~PathComparator() {}
+ virtual ~PathComparator() = default;
+
virtual bool equivalent(StringRef FileA, StringRef FileB) const = 0;
};
-class FileMatchTrieNode;
-/// \brief A trie to efficiently match against the entries of the compilation
+/// A trie to efficiently match against the entries of the compilation
/// database in order of matching suffix length.
///
/// When a clang tool is supposed to operate on a specific file, we have to
@@ -59,32 +58,32 @@ class FileMatchTrie {
public:
FileMatchTrie();
- /// \brief Construct a new \c FileMatchTrie with the given \c PathComparator.
+ /// Construct a new \c FileMatchTrie with the given \c PathComparator.
///
/// The \c FileMatchTrie takes ownership of 'Comparator'. Used for testing.
FileMatchTrie(PathComparator* Comparator);
~FileMatchTrie();
- /// \brief Insert a new absolute path. Relative paths are ignored.
+ /// Insert a new absolute path. Relative paths are ignored.
void insert(StringRef NewPath);
- /// \brief Finds the corresponding file in this trie.
+ /// Finds the corresponding file in this trie.
///
/// Returns file name stored in this trie that is equivalent to 'FileName'
/// according to 'Comparator', if it can be uniquely identified. If there
- /// are no matches an empty \c StringRef is returned. If there are ambigious
+ /// are no matches an empty \c StringRef is returned. If there are ambiguous
/// matches, an empty \c StringRef is returned and a corresponding message
/// written to 'Error'.
StringRef findEquivalent(StringRef FileName,
raw_ostream &Error) const;
+
private:
FileMatchTrieNode *Root;
std::unique_ptr<PathComparator> Comparator;
};
+} // namespace tooling
+} // namespace clang
-} // end namespace tooling
-} // end namespace clang
-
-#endif
+#endif // LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
diff --git a/include/clang/Tooling/FixIt.h b/include/clang/Tooling/FixIt.h
index c1e508849280b..b36f378d6361c 100644
--- a/include/clang/Tooling/FixIt.h
+++ b/include/clang/Tooling/FixIt.h
@@ -29,35 +29,35 @@ namespace fixit {
namespace internal {
StringRef getText(SourceRange Range, const ASTContext &Context);
-/// \brief Returns the SourceRange of a SourceRange. This identity function is
+/// Returns the SourceRange of a SourceRange. This identity function is
/// used by the following template abstractions.
inline SourceRange getSourceRange(const SourceRange &Range) { return Range; }
-/// \brief Returns the SourceRange of the token at Location \p Loc.
+/// Returns the SourceRange of the token at Location \p Loc.
inline SourceRange getSourceRange(const SourceLocation &Loc) {
return SourceRange(Loc);
}
-/// \brief Returns the SourceRange of an given Node. \p Node is typically a
+/// Returns the SourceRange of an given Node. \p Node is typically a
/// 'Stmt', 'Expr' or a 'Decl'.
template <typename T> SourceRange getSourceRange(const T &Node) {
return Node.getSourceRange();
}
} // end namespace internal
-// \brief Returns a textual representation of \p Node.
+// Returns a textual representation of \p Node.
template <typename T>
StringRef getText(const T &Node, const ASTContext &Context) {
return internal::getText(internal::getSourceRange(Node), Context);
}
-// \brief Returns a FixItHint to remove \p Node.
+// Returns a FixItHint to remove \p Node.
// TODO: Add support for related syntactical elements (i.e. comments, ...).
template <typename T> FixItHint createRemoval(const T &Node) {
return FixItHint::CreateRemoval(internal::getSourceRange(Node));
}
-// \brief Returns a FixItHint to replace \p Destination by \p Source.
+// Returns a FixItHint to replace \p Destination by \p Source.
template <typename D, typename S>
FixItHint createReplacement(const D &Destination, const S &Source,
const ASTContext &Context) {
@@ -65,7 +65,7 @@ FixItHint createReplacement(const D &Destination, const S &Source,
getText(Source, Context));
}
-// \brief Returns a FixItHint to replace \p Destination by \p Source.
+// Returns a FixItHint to replace \p Destination by \p Source.
template <typename D>
FixItHint createReplacement(const D &Destination, StringRef Source) {
return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
diff --git a/include/clang/Tooling/Inclusions/HeaderIncludes.h b/include/clang/Tooling/Inclusions/HeaderIncludes.h
new file mode 100644
index 0000000000000..d99a3283168ce
--- /dev/null
+++ b/include/clang/Tooling/Inclusions/HeaderIncludes.h
@@ -0,0 +1,137 @@
+//===--- HeaderIncludes.h - Insert/Delete #includes for C++ code--*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_INCLUSIONS_HEADERINCLUDES_H
+#define LLVM_CLANG_TOOLING_INCLUSIONS_HEADERINCLUDES_H
+
+#include "clang/Basic/SourceManager.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "clang/Tooling/Inclusions/IncludeStyle.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Regex.h"
+#include <unordered_map>
+
+namespace clang {
+namespace tooling {
+
+/// This class manages priorities of C++ #include categories and calculates
+/// priorities for headers.
+/// FIXME(ioeric): move this class into implementation file when clang-format's
+/// include sorting functions are also moved here.
+class IncludeCategoryManager {
+public:
+ IncludeCategoryManager(const IncludeStyle &Style, StringRef FileName);
+
+ /// Returns the priority of the category which \p IncludeName belongs to.
+ /// If \p CheckMainHeader is true and \p IncludeName is a main header, returns
+ /// 0. Otherwise, returns the priority of the matching category or INT_MAX.
+ /// NOTE: this API is not thread-safe!
+ int getIncludePriority(StringRef IncludeName, bool CheckMainHeader) const;
+
+private:
+ bool isMainHeader(StringRef IncludeName) const;
+
+ const IncludeStyle Style;
+ bool IsMainFile;
+ std::string FileName;
+ // This refers to a substring in FileName.
+ StringRef FileStem;
+ // Regex is not thread-safe.
+ mutable SmallVector<llvm::Regex, 4> CategoryRegexs;
+};
+
+/// Generates replacements for inserting or deleting #include directives in a
+/// file.
+class HeaderIncludes {
+public:
+ HeaderIncludes(llvm::StringRef FileName, llvm::StringRef Code,
+ const IncludeStyle &Style);
+
+ /// Inserts an #include directive of \p Header into the code. If \p IsAngled
+ /// is true, \p Header will be quoted with <> in the directive; otherwise, it
+ /// will be quoted with "".
+ ///
+ /// When searching for points to insert new header, this ignores #include's
+ /// after the #include block(s) in the beginning of a file to avoid inserting
+ /// headers into code sections where new #include's should not be added by
+ /// default. These code sections include:
+ /// - raw string literals (containing #include).
+ /// - #if blocks.
+ /// - Special #include's among declarations (e.g. functions).
+ ///
+ /// Returns a replacement that inserts the new header into a suitable #include
+ /// block of the same category. This respects the order of the existing
+ /// #includes in the block; if the existing #includes are not already sorted,
+ /// this will simply insert the #include in front of the first #include of the
+ /// same category in the code that should be sorted after \p IncludeName. If
+ /// \p IncludeName already exists (with exactly the same spelling), this
+ /// returns None.
+ llvm::Optional<tooling::Replacement> insert(llvm::StringRef Header,
+ bool IsAngled) const;
+
+ /// Removes all existing #includes of \p Header quoted with <> if \p IsAngled
+ /// is true or "" if \p IsAngled is false.
+ /// This doesn't resolve the header file path; it only deletes #includes with
+ /// exactly the same spelling.
+ tooling::Replacements remove(llvm::StringRef Header, bool IsAngled) const;
+
+private:
+ struct Include {
+ Include(StringRef Name, tooling::Range R) : Name(Name), R(R) {}
+
+ // An include header quoted with either <> or "".
+ std::string Name;
+ // The range of the whole line of include directive including any eading
+ // whitespaces and trailing comment.
+ tooling::Range R;
+ };
+
+ void addExistingInclude(Include IncludeToAdd, unsigned NextLineOffset);
+
+ std::string FileName;
+ std::string Code;
+
+ // Map from include name (quotation trimmed) to a list of existing includes
+ // (in case there are more than one) with the name in the current file. <x>
+ // and "x" will be treated as the same header when deleting #includes.
+ llvm::StringMap<llvm::SmallVector<Include, 1>> ExistingIncludes;
+
+ /// Map from priorities of #include categories to all #includes in the same
+ /// category. This is used to find #includes of the same category when
+ /// inserting new #includes. #includes in the same categories are sorted in
+ /// in the order they appear in the source file.
+ /// See comment for "FormatStyle::IncludeCategories" for details about include
+ /// priorities.
+ std::unordered_map<int, llvm::SmallVector<const Include *, 8>>
+ IncludesByPriority;
+
+ int FirstIncludeOffset;
+ // All new headers should be inserted after this offset (e.g. after header
+ // guards, file comment).
+ unsigned MinInsertOffset;
+ // Max insertion offset in the original code. For example, we want to avoid
+ // inserting new #includes into the actual code section (e.g. after a
+ // declaration).
+ unsigned MaxInsertOffset;
+ IncludeCategoryManager Categories;
+ // Record the offset of the end of the last include in each category.
+ std::unordered_map<int, int> CategoryEndOffsets;
+
+ // All possible priorities.
+ std::set<int> Priorities;
+
+ // Matches a whole #include directive.
+ llvm::Regex IncludeRegex;
+};
+
+
+} // namespace tooling
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLING_INCLUSIONS_HEADERINCLUDES_H
diff --git a/include/clang/Tooling/Inclusions/IncludeStyle.h b/include/clang/Tooling/Inclusions/IncludeStyle.h
new file mode 100644
index 0000000000000..a093dff277288
--- /dev/null
+++ b/include/clang/Tooling/Inclusions/IncludeStyle.h
@@ -0,0 +1,139 @@
+//===--- IncludeStyle.h - Style of C++ #include directives -------*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H
+#define LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H
+
+#include "llvm/Support/YAMLTraits.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace tooling {
+
+/// Style for sorting and grouping C++ #include directives.
+struct IncludeStyle {
+ /// Styles for sorting multiple ``#include`` blocks.
+ enum IncludeBlocksStyle {
+ /// Sort each ``#include`` block separately.
+ /// \code
+ /// #include "b.h" into #include "b.h"
+ ///
+ /// #include <lib/main.h> #include "a.h"
+ /// #include "a.h" #include <lib/main.h>
+ /// \endcode
+ IBS_Preserve,
+ /// Merge multiple ``#include`` blocks together and sort as one.
+ /// \code
+ /// #include "b.h" into #include "a.h"
+ /// #include "b.h"
+ /// #include <lib/main.h> #include <lib/main.h>
+ /// #include "a.h"
+ /// \endcode
+ IBS_Merge,
+ /// Merge multiple ``#include`` blocks together and sort as one.
+ /// Then split into groups based on category priority. See
+ /// ``IncludeCategories``.
+ /// \code
+ /// #include "b.h" into #include "a.h"
+ /// #include "b.h"
+ /// #include <lib/main.h>
+ /// #include "a.h" #include <lib/main.h>
+ /// \endcode
+ IBS_Regroup,
+ };
+
+ /// Dependent on the value, multiple ``#include`` blocks can be sorted
+ /// as one and divided based on category.
+ IncludeBlocksStyle IncludeBlocks;
+
+ /// See documentation of ``IncludeCategories``.
+ struct IncludeCategory {
+ /// The regular expression that this category matches.
+ std::string Regex;
+ /// The priority to assign to this category.
+ int Priority;
+ bool operator==(const IncludeCategory &Other) const {
+ return Regex == Other.Regex && Priority == Other.Priority;
+ }
+ };
+
+ /// Regular expressions denoting the different ``#include`` categories
+ /// used for ordering ``#includes``.
+ ///
+ /// `POSIX extended
+ /// <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_
+ /// regular expressions are supported.
+ ///
+ /// These regular expressions are matched against the filename of an include
+ /// (including the <> or "") in order. The value belonging to the first
+ /// matching regular expression is assigned and ``#includes`` are sorted first
+ /// according to increasing category number and then alphabetically within
+ /// each category.
+ ///
+ /// If none of the regular expressions match, INT_MAX is assigned as
+ /// category. The main header for a source file automatically gets category 0.
+ /// so that it is generally kept at the beginning of the ``#includes``
+ /// (http://llvm.org/docs/CodingStandards.html#include-style). However, you
+ /// can also assign negative priorities if you have certain headers that
+ /// always need to be first.
+ ///
+ /// To configure this in the .clang-format file, use:
+ /// \code{.yaml}
+ /// IncludeCategories:
+ /// - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
+ /// Priority: 2
+ /// - Regex: '^(<|"(gtest|gmock|isl|json)/)'
+ /// Priority: 3
+ /// - Regex: '<[[:alnum:].]+>'
+ /// Priority: 4
+ /// - Regex: '.*'
+ /// Priority: 1
+ /// \endcode
+ std::vector<IncludeCategory> IncludeCategories;
+
+ /// Specify a regular expression of suffixes that are allowed in the
+ /// file-to-main-include mapping.
+ ///
+ /// When guessing whether a #include is the "main" include (to assign
+ /// category 0, see above), use this regex of allowed suffixes to the header
+ /// stem. A partial match is done, so that:
+ /// - "" means "arbitrary suffix"
+ /// - "$" means "no suffix"
+ ///
+ /// For example, if configured to "(_test)?$", then a header a.h would be seen
+ /// as the "main" include in both a.cc and a_test.cc.
+ std::string IncludeIsMainRegex;
+};
+
+} // namespace tooling
+} // namespace clang
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::IncludeStyle::IncludeCategory)
+
+namespace llvm {
+namespace yaml {
+
+template <>
+struct MappingTraits<clang::tooling::IncludeStyle::IncludeCategory> {
+ static void mapping(IO &IO,
+ clang::tooling::IncludeStyle::IncludeCategory &Category);
+};
+
+template <>
+struct ScalarEnumerationTraits<
+ clang::tooling::IncludeStyle::IncludeBlocksStyle> {
+ static void
+ enumeration(IO &IO, clang::tooling::IncludeStyle::IncludeBlocksStyle &Value);
+};
+
+} // namespace yaml
+} // namespace llvm
+
+#endif // LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H
diff --git a/include/clang/Tooling/JSONCompilationDatabase.h b/include/clang/Tooling/JSONCompilationDatabase.h
index 9a6866240b08c..882afc6d9ece2 100644
--- a/include/clang/Tooling/JSONCompilationDatabase.h
+++ b/include/clang/Tooling/JSONCompilationDatabase.h
@@ -1,4 +1,4 @@
-//===--- JSONCompilationDatabase.h - ----------------------------*- C++ -*-===//
+//===- JSONCompilationDatabase.h --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,6 +18,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/FileMatchTrie.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -25,12 +26,14 @@
#include "llvm/Support/YAMLParser.h"
#include <memory>
#include <string>
+#include <tuple>
+#include <utility>
#include <vector>
namespace clang {
namespace tooling {
-/// \brief A JSON based compilation database.
+/// A JSON based compilation database.
///
/// JSON compilation database files must contain a list of JSON objects which
/// provide the command lines in the attributes 'directory', 'command',
@@ -58,7 +61,7 @@ namespace tooling {
enum class JSONCommandLineSyntax { Windows, Gnu, AutoDetect };
class JSONCompilationDatabase : public CompilationDatabase {
public:
- /// \brief Loads a JSON compilation database from the specified file.
+ /// Loads a JSON compilation database from the specified file.
///
/// Returns NULL and sets ErrorMessage if the database could not be
/// loaded from the given file.
@@ -66,14 +69,14 @@ public:
loadFromFile(StringRef FilePath, std::string &ErrorMessage,
JSONCommandLineSyntax Syntax);
- /// \brief Loads a JSON compilation database from a data buffer.
+ /// Loads a JSON compilation database from a data buffer.
///
/// Returns NULL and sets ErrorMessage if the database could not be loaded.
static std::unique_ptr<JSONCompilationDatabase>
loadFromBuffer(StringRef DatabaseString, std::string &ErrorMessage,
JSONCommandLineSyntax Syntax);
- /// \brief Returns all compile commands in which the specified file was
+ /// Returns all compile commands in which the specified file was
/// compiled.
///
/// FIXME: Currently FilePath must be an absolute path inside the
@@ -81,23 +84,23 @@ public:
std::vector<CompileCommand>
getCompileCommands(StringRef FilePath) const override;
- /// \brief Returns the list of all files available in the compilation database.
+ /// Returns the list of all files available in the compilation database.
///
/// These are the 'file' entries of the JSON objects.
std::vector<std::string> getAllFiles() const override;
- /// \brief Returns all compile commands for all the files in the compilation
+ /// Returns all compile commands for all the files in the compilation
/// database.
std::vector<CompileCommand> getAllCompileCommands() const override;
private:
- /// \brief Constructs a JSON compilation database on a memory buffer.
+ /// Constructs a JSON compilation database on a memory buffer.
JSONCompilationDatabase(std::unique_ptr<llvm::MemoryBuffer> Database,
JSONCommandLineSyntax Syntax)
: Database(std::move(Database)), Syntax(Syntax),
YAMLStream(this->Database->getBuffer(), SM) {}
- /// \brief Parses the database file and creates the index.
+ /// Parses the database file and creates the index.
///
/// Returns whether parsing succeeded. Sets ErrorMessage if parsing
/// failed.
@@ -110,12 +113,12 @@ private:
// Otherwise, each entry in the command line vector is a literal
// argument to the compiler.
// The output field may be a nullptr.
- typedef std::tuple<llvm::yaml::ScalarNode *,
- llvm::yaml::ScalarNode *,
- std::vector<llvm::yaml::ScalarNode *>,
- llvm::yaml::ScalarNode *> CompileCommandRef;
+ using CompileCommandRef =
+ std::tuple<llvm::yaml::ScalarNode *, llvm::yaml::ScalarNode *,
+ std::vector<llvm::yaml::ScalarNode *>,
+ llvm::yaml::ScalarNode *>;
- /// \brief Converts the given array of CompileCommandRefs to CompileCommands.
+ /// Converts the given array of CompileCommandRefs to CompileCommands.
void getCommands(ArrayRef<CompileCommandRef> CommandsRef,
std::vector<CompileCommand> &Commands) const;
@@ -134,7 +137,7 @@ private:
llvm::yaml::Stream YAMLStream;
};
-} // end namespace tooling
-} // end namespace clang
+} // namespace tooling
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_TOOLING_JSONCOMPILATIONDATABASE_H
diff --git a/include/clang/Tooling/Refactoring.h b/include/clang/Tooling/Refactoring.h
index bc95c3b09ec2d..64b018ea26c2c 100644
--- a/include/clang/Tooling/Refactoring.h
+++ b/include/clang/Tooling/Refactoring.h
@@ -30,7 +30,7 @@ class Rewriter;
namespace tooling {
-/// \brief A tool to run refactorings.
+/// A tool to run refactorings.
///
/// This is a refactoring specific version of \see ClangTool. FrontendActions
/// passed to run() and runAndSave() should add replacements to
@@ -43,17 +43,17 @@ public:
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>());
- /// \brief Returns the file path to replacements map to which replacements
+ /// Returns the file path to replacements map to which replacements
/// should be added during the run of the tool.
std::map<std::string, Replacements> &getReplacements();
- /// \brief Call run(), apply all generated replacements, and immediately save
+ /// Call run(), apply all generated replacements, and immediately save
/// the results to disk.
///
/// \returns 0 upon success. Non-zero upon failure.
int runAndSave(FrontendActionFactory *ActionFactory);
- /// \brief Apply all stored replacements to the given Rewriter.
+ /// Apply all stored replacements to the given Rewriter.
///
/// FileToReplaces will be deduplicated with `groupReplacementsByFile` before
/// application.
@@ -65,14 +65,14 @@ public:
bool applyAllReplacements(Rewriter &Rewrite);
private:
- /// \brief Write all refactored files to disk.
+ /// Write all refactored files to disk.
int saveRewrittenFiles(Rewriter &Rewrite);
private:
std::map<std::string, Replacements> FileToReplaces;
};
-/// \brief Groups \p Replaces by the file path and applies each group of
+/// Groups \p Replaces by the file path and applies each group of
/// Replacements on the related file in \p Rewriter. In addition to applying
/// given Replacements, this function also formats the changed code.
///
diff --git a/include/clang/Tooling/Refactoring/AtomicChange.h b/include/clang/Tooling/Refactoring/AtomicChange.h
index 8a468a6de84ef..bfe042fc53c52 100644
--- a/include/clang/Tooling/Refactoring/AtomicChange.h
+++ b/include/clang/Tooling/Refactoring/AtomicChange.h
@@ -24,7 +24,7 @@
namespace clang {
namespace tooling {
-/// \brief An atomic change is used to create and group a set of source edits,
+/// An atomic change is used to create and group a set of source edits,
/// e.g. replacements or header insertions. Edits in an AtomicChange should be
/// related, e.g. replacements for the same type reference and the corresponding
/// header insertion/deletion.
@@ -36,13 +36,13 @@ namespace tooling {
/// bad, i.e. none of its source edits will be applied.
class AtomicChange {
public:
- /// \brief Creates an atomic change around \p KeyPosition with the key being a
+ /// Creates an atomic change around \p KeyPosition with the key being a
/// concatenation of the file name and the offset of \p KeyPosition.
/// \p KeyPosition should be the location of the key syntactical element that
/// is being changed, e.g. the call to a refactored method.
AtomicChange(const SourceManager &SM, SourceLocation KeyPosition);
- /// \brief Creates an atomic change for \p FilePath with a customized key.
+ /// Creates an atomic change for \p FilePath with a customized key.
AtomicChange(llvm::StringRef FilePath, llvm::StringRef Key)
: Key(Key), FilePath(FilePath) {}
@@ -54,44 +54,44 @@ public:
bool operator==(const AtomicChange &Other) const;
- /// \brief Returns the atomic change as a YAML string.
+ /// Returns the atomic change as a YAML string.
std::string toYAMLString();
- /// \brief Converts a YAML-encoded automic change to AtomicChange.
+ /// Converts a YAML-encoded automic change to AtomicChange.
static AtomicChange convertFromYAML(llvm::StringRef YAMLContent);
- /// \brief Returns the key of this change, which is a concatenation of the
+ /// Returns the key of this change, which is a concatenation of the
/// file name and offset of the key position.
const std::string &getKey() const { return Key; }
- /// \brief Returns the path of the file containing this atomic change.
+ /// Returns the path of the file containing this atomic change.
const std::string &getFilePath() const { return FilePath; }
- /// \brief If this change could not be created successfully, e.g. because of
+ /// If this change could not be created successfully, e.g. because of
/// conflicts among replacements, use this to set an error description.
/// Thereby, places that cannot be fixed automatically can be gathered when
/// applying changes.
void setError(llvm::StringRef Error) { this->Error = Error; }
- /// \brief Returns whether an error has been set on this list.
+ /// Returns whether an error has been set on this list.
bool hasError() const { return !Error.empty(); }
- /// \brief Returns the error message or an empty string if it does not exist.
+ /// Returns the error message or an empty string if it does not exist.
const std::string &getError() const { return Error; }
- /// \brief Adds a replacement that replaces the given Range with
+ /// Adds a replacement that replaces the given Range with
/// ReplacementText.
/// \returns An llvm::Error carrying ReplacementError on error.
llvm::Error replace(const SourceManager &SM, const CharSourceRange &Range,
llvm::StringRef ReplacementText);
- /// \brief Adds a replacement that replaces range [Loc, Loc+Length) with
+ /// Adds a replacement that replaces range [Loc, Loc+Length) with
/// \p Text.
/// \returns An llvm::Error carrying ReplacementError on error.
llvm::Error replace(const SourceManager &SM, SourceLocation Loc,
unsigned Length, llvm::StringRef Text);
- /// \brief Adds a replacement that inserts \p Text at \p Loc. If this
+ /// Adds a replacement that inserts \p Text at \p Loc. If this
/// insertion conflicts with an existing insertion (at the same position),
/// this will be inserted before/after the existing insertion depending on
/// \p InsertAfter. Users should use `replace` with `Length=0` instead if they
@@ -102,15 +102,15 @@ public:
llvm::Error insert(const SourceManager &SM, SourceLocation Loc,
llvm::StringRef Text, bool InsertAfter = true);
- /// \brief Adds a header into the file that contains the key position.
+ /// Adds a header into the file that contains the key position.
/// Header can be in angle brackets or double quotation marks. By default
/// (header is not quoted), header will be surrounded with double quotes.
void addHeader(llvm::StringRef Header);
- /// \brief Removes a header from the file that contains the key position.
+ /// Removes a header from the file that contains the key position.
void removeHeader(llvm::StringRef Header);
- /// \brief Returns a const reference to existing replacements.
+ /// Returns a const reference to existing replacements.
const Replacements &getReplacements() const { return Replaces; }
llvm::ArrayRef<std::string> getInsertedHeaders() const {
@@ -158,7 +158,7 @@ struct ApplyChangesSpec {
FormatOption Format = kNone;
};
-/// \brief Applies all AtomicChanges in \p Changes to the \p Code.
+/// Applies all AtomicChanges in \p Changes to the \p Code.
///
/// This completely ignores the file path in each change and replaces them with
/// \p FilePath, i.e. callers are responsible for ensuring all changes are for
diff --git a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
index d96ad78ad8768..d2d47ddc2c61c 100644
--- a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
+++ b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief A wrapper class around \c RecursiveASTVisitor that visits each
+/// A wrapper class around \c RecursiveASTVisitor that visits each
/// occurrences of a named symbol.
///
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRule.h b/include/clang/Tooling/Refactoring/RefactoringActionRule.h
index 4130e29d8dea5..ce4a91cbbadce 100644
--- a/include/clang/Tooling/Refactoring/RefactoringActionRule.h
+++ b/include/clang/Tooling/Refactoring/RefactoringActionRule.h
@@ -56,7 +56,7 @@ public:
class RefactoringActionRule : public RefactoringActionRuleBase {
public:
/// Returns true when the rule has a source selection requirement that has
- /// to be fullfilled before refactoring can be performed.
+ /// to be fulfilled before refactoring can be performed.
virtual bool hasSelectionRequirement() = 0;
/// Traverses each refactoring option used by the rule and invokes the
diff --git a/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h b/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h
index fe7738e734997..005eb877bf0fd 100644
--- a/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h
+++ b/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h
@@ -26,8 +26,8 @@ class RefactoringResultConsumer {
public:
virtual ~RefactoringResultConsumer() {}
- /// Handles an initation or an invication error. An initiation error typically
- /// has a \c DiagnosticError payload that describes why initation failed.
+ /// Handles an initiation or an invication error. An initiation error typically
+ /// has a \c DiagnosticError payload that describes why initiation failed.
virtual void handleError(llvm::Error Err) = 0;
/// Handles the source replacements that are produced by a refactoring action.
diff --git a/include/clang/Tooling/Refactoring/Rename/RenamingAction.h b/include/clang/Tooling/Refactoring/Rename/RenamingAction.h
index 734b624d777ba..5771a1c2d1328 100644
--- a/include/clang/Tooling/Refactoring/Rename/RenamingAction.h
+++ b/include/clang/Tooling/Refactoring/Rename/RenamingAction.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Provides an action to rename every symbol at a point.
+/// Provides an action to rename every symbol at a point.
///
//===----------------------------------------------------------------------===//
@@ -82,7 +82,7 @@ private:
Expected<AtomicChanges>
createSourceReplacements(RefactoringRuleContext &Context) override;
- // A NamedDecl which indentifies the the symbol being renamed.
+ // A NamedDecl which identifies the symbol being renamed.
const NamedDecl *ND;
// The new qualified name to change the symbol to.
std::string NewQualifiedName;
diff --git a/include/clang/Tooling/Refactoring/Rename/SymbolName.h b/include/clang/Tooling/Refactoring/Rename/SymbolName.h
index e69d2908b5d30..42e0a5cb6697d 100644
--- a/include/clang/Tooling/Refactoring/Rename/SymbolName.h
+++ b/include/clang/Tooling/Refactoring/Rename/SymbolName.h
@@ -21,7 +21,7 @@ namespace tooling {
/// A name of a symbol.
///
/// Symbol's name can be composed of multiple strings. For example, Objective-C
-/// methods can contain multiple argument lables:
+/// methods can contain multiple argument labels:
///
/// \code
/// - (void) myMethodNamePiece: (int)x anotherNamePieces:(int)y;
diff --git a/include/clang/Tooling/Refactoring/Rename/USRFinder.h b/include/clang/Tooling/Refactoring/Rename/USRFinder.h
index b74a5d7f70af3..3622bd0daf855 100644
--- a/include/clang/Tooling/Refactoring/Rename/USRFinder.h
+++ b/include/clang/Tooling/Refactoring/Rename/USRFinder.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Methods for determining the USR of a symbol at a location in source
+/// Methods for determining the USR of a symbol at a location in source
/// code.
///
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h b/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h
index f1c5ae60f875c..ebc9790e9cb63 100644
--- a/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h
+++ b/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Provides an action to find all relevant USRs at a point.
+/// Provides an action to find all relevant USRs at a point.
///
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h b/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
index 801a8ad9e99c6..e1228e9f39f76 100644
--- a/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
+++ b/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief Provides functionality for finding all instances of a USR in a given
+/// Provides functionality for finding all instances of a USR in a given
/// AST.
///
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/RefactoringCallbacks.h b/include/clang/Tooling/RefactoringCallbacks.h
index 9862951149a3a..2137e0035d629 100644
--- a/include/clang/Tooling/RefactoringCallbacks.h
+++ b/include/clang/Tooling/RefactoringCallbacks.h
@@ -35,7 +35,7 @@
namespace clang {
namespace tooling {
-/// \brief Base class for RefactoringCallbacks.
+/// Base class for RefactoringCallbacks.
///
/// Collects \c tooling::Replacements while running.
class RefactoringCallback : public ast_matchers::MatchFinder::MatchCallback {
@@ -47,7 +47,7 @@ protected:
Replacements Replace;
};
-/// \brief Adaptor between \c ast_matchers::MatchFinder and \c
+/// Adaptor between \c ast_matchers::MatchFinder and \c
/// tooling::RefactoringTool.
///
/// Runs AST matchers and stores the \c tooling::Replacements in a map.
@@ -74,7 +74,7 @@ private:
std::map<std::string, Replacements> &FileToReplaces;
};
-/// \brief Replace the text of the statement bound to \c FromId with the text in
+/// Replace the text of the statement bound to \c FromId with the text in
/// \c ToText.
class ReplaceStmtWithText : public RefactoringCallback {
public:
@@ -86,7 +86,7 @@ private:
std::string ToText;
};
-/// \brief Replace the text of an AST node bound to \c FromId with the result of
+/// Replace the text of an AST node bound to \c FromId with the result of
/// evaluating the template in \c ToTemplate.
///
/// Expressions of the form ${NodeName} in \c ToTemplate will be
@@ -109,7 +109,7 @@ private:
std::vector<TemplateElement> Template;
};
-/// \brief Replace the text of the statement bound to \c FromId with the text of
+/// Replace the text of the statement bound to \c FromId with the text of
/// the statement bound to \c ToId.
class ReplaceStmtWithStmt : public RefactoringCallback {
public:
@@ -121,7 +121,7 @@ private:
std::string ToId;
};
-/// \brief Replace an if-statement bound to \c Id with the outdented text of its
+/// Replace an if-statement bound to \c Id with the outdented text of its
/// body, choosing the consequent or the alternative based on whether
/// \c PickTrueBranch is true.
class ReplaceIfStmtWithItsBody : public RefactoringCallback {
diff --git a/include/clang/Tooling/ReplacementsYaml.h b/include/clang/Tooling/ReplacementsYaml.h
index 0b1dc4c774231..8e41525a9412a 100644
--- a/include/clang/Tooling/ReplacementsYaml.h
+++ b/include/clang/Tooling/ReplacementsYaml.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief This file defines the structure of a YAML document for serializing
+/// This file defines the structure of a YAML document for serializing
/// replacements.
///
//===----------------------------------------------------------------------===//
@@ -25,10 +25,10 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Replacement)
namespace llvm {
namespace yaml {
-/// \brief Specialized MappingTraits to describe how a Replacement is
+/// Specialized MappingTraits to describe how a Replacement is
/// (de)serialized.
template <> struct MappingTraits<clang::tooling::Replacement> {
- /// \brief Helper to (de)serialize a Replacement since we don't have direct
+ /// Helper to (de)serialize a Replacement since we don't have direct
/// access to its data members.
struct NormalizedReplacement {
NormalizedReplacement(const IO &)
@@ -59,7 +59,7 @@ template <> struct MappingTraits<clang::tooling::Replacement> {
}
};
-/// \brief Specialized MappingTraits to describe how a
+/// Specialized MappingTraits to describe how a
/// TranslationUnitReplacements is (de)serialized.
template <> struct MappingTraits<clang::tooling::TranslationUnitReplacements> {
static void mapping(IO &Io,
diff --git a/include/clang/Tooling/StandaloneExecution.h b/include/clang/Tooling/StandaloneExecution.h
index f5f32d737a452..572330e4cc220 100644
--- a/include/clang/Tooling/StandaloneExecution.h
+++ b/include/clang/Tooling/StandaloneExecution.h
@@ -20,7 +20,7 @@
namespace clang {
namespace tooling {
-/// \brief A standalone executor that runs FrontendActions on a given set of
+/// A standalone executor that runs FrontendActions on a given set of
/// TUs in sequence.
///
/// By default, this executor uses the following arguments adjusters (as defined
@@ -32,15 +32,16 @@ class StandaloneToolExecutor : public ToolExecutor {
public:
static const char *ExecutorName;
- /// \brief Init with \p CompilationDatabase and the paths of all files to be
+ /// Init with \p CompilationDatabase and the paths of all files to be
/// proccessed.
StandaloneToolExecutor(
const CompilationDatabase &Compilations,
llvm::ArrayRef<std::string> SourcePaths,
+ IntrusiveRefCntPtr<vfs::FileSystem> BaseFS = vfs::getRealFileSystem(),
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>());
- /// \brief Init with \p CommonOptionsParser. This is expected to be used by
+ /// Init with \p CommonOptionsParser. This is expected to be used by
/// `createExecutorFromCommandLineArgs` based on commandline options.
///
/// The executor takes ownership of \p Options.
@@ -58,7 +59,7 @@ public:
std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
Actions) override;
- /// \brief Set a \c DiagnosticConsumer to use during parsing.
+ /// Set a \c DiagnosticConsumer to use during parsing.
void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
Tool.setDiagnosticConsumer(DiagConsumer);
}
@@ -75,7 +76,7 @@ public:
Tool.mapVirtualFile(FilePath, Content);
}
- /// \brief Returns the file manager used in the tool.
+ /// Returns the file manager used in the tool.
///
/// The file manager is shared between all translation units.
FileManager &getFiles() { return Tool.getFiles(); }
diff --git a/include/clang/Tooling/ToolExecutorPluginRegistry.h b/include/clang/Tooling/ToolExecutorPluginRegistry.h
index 11ba89546e9ea..921689dff86f1 100644
--- a/include/clang/Tooling/ToolExecutorPluginRegistry.h
+++ b/include/clang/Tooling/ToolExecutorPluginRegistry.h
@@ -1,4 +1,4 @@
-//===--- ToolExecutorPluginRegistry.h - -------------------------*- C++ -*-===//
+//===- ToolExecutorPluginRegistry.h -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,9 +16,9 @@
namespace clang {
namespace tooling {
-typedef llvm::Registry<ToolExecutorPlugin> ToolExecutorPluginRegistry;
+using ToolExecutorPluginRegistry = llvm::Registry<ToolExecutorPlugin>;
-} // end namespace tooling
-} // end namespace clang
+} // namespace tooling
+} // namespace clang
#endif // LLVM_CLANG_TOOLING_TOOLEXECUTORPLUGINREGISTRY_H
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
index e64be07d9ab44..c056894b1a7af 100644
--- a/include/clang/Tooling/Tooling.h
+++ b/include/clang/Tooling/Tooling.h
@@ -1,4 +1,4 @@
-//===--- Tooling.h - Framework for standalone Clang tools -------*- C++ -*-===//
+//===- Tooling.h - Framework for standalone Clang tools ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -31,35 +31,43 @@
#define LLVM_CLANG_TOOLING_TOOLING_H
#include "clang/AST/ASTConsumer.h"
-#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h"
-#include "clang/Driver/Util.h"
+#include "clang/Basic/VirtualFileSystem.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/PCHContainerOperations.h"
-#include "clang/Lex/ModuleLoader.h"
#include "clang/Tooling/ArgumentsAdjusters.h"
-#include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Option/Option.h"
#include <memory>
#include <string>
+#include <utility>
#include <vector>
namespace clang {
+class CompilerInstance;
+class CompilerInvocation;
+class DiagnosticConsumer;
+class DiagnosticsEngine;
+class SourceManager;
+
namespace driver {
+
class Compilation;
-} // end namespace driver
-class CompilerInvocation;
-class SourceManager;
-class FrontendAction;
+} // namespace driver
namespace tooling {
-/// \brief Interface to process a clang::CompilerInvocation.
+class CompilationDatabase;
+
+/// Interface to process a clang::CompilerInvocation.
///
/// If your tool is based on FrontendAction, you should be deriving from
/// FrontendActionFactory instead.
@@ -67,15 +75,15 @@ class ToolAction {
public:
virtual ~ToolAction();
- /// \brief Perform an action for an invocation.
+ /// Perform an action for an invocation.
virtual bool
- runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation,
+ runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
FileManager *Files,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
DiagnosticConsumer *DiagConsumer) = 0;
};
-/// \brief Interface to generate clang::FrontendActions.
+/// Interface to generate clang::FrontendActions.
///
/// Having a factory interface allows, for example, a new FrontendAction to be
/// created for each translation unit processed by ClangTool. This class is
@@ -85,19 +93,19 @@ class FrontendActionFactory : public ToolAction {
public:
~FrontendActionFactory() override;
- /// \brief Invokes the compiler with a FrontendAction created by create().
- bool runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation,
+ /// Invokes the compiler with a FrontendAction created by create().
+ bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
FileManager *Files,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
DiagnosticConsumer *DiagConsumer) override;
- /// \brief Returns a new clang::FrontendAction.
+ /// Returns a new clang::FrontendAction.
///
/// The caller takes ownership of the returned action.
- virtual clang::FrontendAction *create() = 0;
+ virtual FrontendAction *create() = 0;
};
-/// \brief Returns a new FrontendActionFactory for a given type.
+/// Returns a new FrontendActionFactory for a given type.
///
/// T must derive from clang::FrontendAction.
///
@@ -107,25 +115,25 @@ public:
template <typename T>
std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
-/// \brief Callbacks called before and after each source file processed by a
+/// Callbacks called before and after each source file processed by a
/// FrontendAction created by the FrontedActionFactory returned by \c
/// newFrontendActionFactory.
class SourceFileCallbacks {
public:
- virtual ~SourceFileCallbacks() {}
+ virtual ~SourceFileCallbacks() = default;
- /// \brief Called before a source file is processed by a FrontEndAction.
+ /// Called before a source file is processed by a FrontEndAction.
/// \see clang::FrontendAction::BeginSourceFileAction
virtual bool handleBeginSource(CompilerInstance &CI) {
return true;
}
- /// \brief Called after a source file is processed by a FrontendAction.
+ /// Called after a source file is processed by a FrontendAction.
/// \see clang::FrontendAction::EndSourceFileAction
virtual void handleEndSource() {}
};
-/// \brief Returns a new FrontendActionFactory for any type that provides an
+/// Returns a new FrontendActionFactory for any type that provides an
/// implementation of newASTConsumer().
///
/// FactoryT must implement: ASTConsumer *newASTConsumer().
@@ -140,7 +148,7 @@ template <typename FactoryT>
inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = nullptr);
-/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
+/// Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
///
/// \param ToolAction The action to run over the code.
/// \param Code C++ code.
@@ -149,16 +157,16 @@ inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
/// clang modules.
///
/// \return - True if 'ToolAction' was successfully executed.
-bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
+bool runToolOnCode(FrontendAction *ToolAction, const Twine &Code,
const Twine &FileName = "input.cc",
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>());
/// The first part of the pair is the filename, the second part the
/// file-content.
-typedef std::vector<std::pair<std::string, std::string>> FileContentMappings;
+using FileContentMappings = std::vector<std::pair<std::string, std::string>>;
-/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
+/// Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
/// with additional other flags.
///
/// \param ToolAction The action to run over the code.
@@ -172,14 +180,23 @@ typedef std::vector<std::pair<std::string, std::string>> FileContentMappings;
///
/// \return - True if 'ToolAction' was successfully executed.
bool runToolOnCodeWithArgs(
- clang::FrontendAction *ToolAction, const Twine &Code,
+ FrontendAction *ToolAction, const Twine &Code,
const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
const Twine &ToolName = "clang-tool",
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>(),
const FileContentMappings &VirtualMappedFiles = FileContentMappings());
-/// \brief Builds an AST for 'Code'.
+// Similar to the overload except this takes a VFS.
+bool runToolOnCodeWithArgs(
+ FrontendAction *ToolAction, const Twine &Code,
+ llvm::IntrusiveRefCntPtr<vfs::FileSystem> VFS,
+ const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
+ const Twine &ToolName = "clang-tool",
+ std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+ std::make_shared<PCHContainerOperations>());
+
+/// Builds an AST for 'Code'.
///
/// \param Code C++ code.
/// \param FileName The file name which 'Code' will be mapped as.
@@ -192,7 +209,7 @@ buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc",
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>());
-/// \brief Builds an AST for 'Code' with additional flags.
+/// Builds an AST for 'Code' with additional flags.
///
/// \param Code C++ code.
/// \param Args Additional flags to pass on.
@@ -212,10 +229,10 @@ std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
std::make_shared<PCHContainerOperations>(),
ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster());
-/// \brief Utility to run a FrontendAction in a single clang invocation.
+/// Utility to run a FrontendAction in a single clang invocation.
class ToolInvocation {
public:
- /// \brief Create a tool invocation.
+ /// Create a tool invocation.
///
/// \param CommandLine The command line arguments to clang. Note that clang
/// uses its binary name (CommandLine[0]) to locate its builtin headers.
@@ -231,7 +248,7 @@ public:
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>());
- /// \brief Create a tool invocation.
+ /// Create a tool invocation.
///
/// \param CommandLine The command line arguments to clang.
/// \param Action The action to be executed.
@@ -244,19 +261,19 @@ public:
~ToolInvocation();
- /// \brief Set a \c DiagnosticConsumer to use during parsing.
+ /// Set a \c DiagnosticConsumer to use during parsing.
void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
this->DiagConsumer = DiagConsumer;
}
- /// \brief Map a virtual file to be used while running the tool.
+ /// Map a virtual file to be used while running the tool.
///
/// \param FilePath The path at which the content will be mapped.
/// \param Content A null terminated buffer of the file's content.
// FIXME: remove this when all users have migrated!
void mapVirtualFile(StringRef FilePath, StringRef Content);
- /// \brief Run the clang invocation.
+ /// Run the clang invocation.
///
/// \returns True if there were no errors during execution.
bool run();
@@ -265,8 +282,8 @@ public:
void addFileMappingsTo(SourceManager &SourceManager);
bool runInvocation(const char *BinaryName,
- clang::driver::Compilation *Compilation,
- std::shared_ptr<clang::CompilerInvocation> Invocation,
+ driver::Compilation *Compilation,
+ std::shared_ptr<CompilerInvocation> Invocation,
std::shared_ptr<PCHContainerOperations> PCHContainerOps);
std::vector<std::string> CommandLine;
@@ -276,10 +293,10 @@ public:
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
// Maps <file name> -> <file content>.
llvm::StringMap<StringRef> MappedFileContents;
- DiagnosticConsumer *DiagConsumer;
+ DiagnosticConsumer *DiagConsumer = nullptr;
};
-/// \brief Utility to run a FrontendAction over a set of files.
+/// Utility to run a FrontendAction over a set of files.
///
/// This class is written to be usable for command line utilities.
/// By default the class uses ClangSyntaxOnlyAdjuster to modify
@@ -287,8 +304,8 @@ public:
/// a frontend action. One could install an additional command line
/// arguments adjuster by calling the appendArgumentsAdjuster() method.
class ClangTool {
- public:
- /// \brief Constructs a clang tool to run over a list of files.
+public:
+ /// Constructs a clang tool to run over a list of files.
///
/// \param Compilations The CompilationDatabase which contains the compile
/// command lines for the given source paths.
@@ -296,43 +313,50 @@ class ClangTool {
/// not found in Compilations, it is skipped.
/// \param PCHContainerOps The PCHContainerOperations for loading and creating
/// clang modules.
+ /// \param BaseFS VFS used for all underlying file accesses when running the
+ /// tool.
ClangTool(const CompilationDatabase &Compilations,
ArrayRef<std::string> SourcePaths,
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
- std::make_shared<PCHContainerOperations>());
+ std::make_shared<PCHContainerOperations>(),
+ IntrusiveRefCntPtr<vfs::FileSystem> BaseFS =
+ vfs::getRealFileSystem());
~ClangTool();
- /// \brief Set a \c DiagnosticConsumer to use during parsing.
+ /// Set a \c DiagnosticConsumer to use during parsing.
void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
this->DiagConsumer = DiagConsumer;
}
- /// \brief Map a virtual file to be used while running the tool.
+ /// Map a virtual file to be used while running the tool.
///
/// \param FilePath The path at which the content will be mapped.
/// \param Content A null terminated buffer of the file's content.
void mapVirtualFile(StringRef FilePath, StringRef Content);
- /// \brief Append a command line arguments adjuster to the adjuster chain.
+ /// Append a command line arguments adjuster to the adjuster chain.
///
/// \param Adjuster An argument adjuster, which will be run on the output of
/// previous argument adjusters.
void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
- /// \brief Clear the command line arguments adjuster chain.
+ /// Clear the command line arguments adjuster chain.
void clearArgumentsAdjusters();
/// Runs an action over all files specified in the command line.
///
/// \param Action Tool action.
+ ///
+ /// \returns 0 on success; 1 if any error occurred; 2 if there is no error but
+ /// some files are skipped due to missing compile commands.
int run(ToolAction *Action);
- /// \brief Create an AST for each file specified in the command line and
+ /// Create an AST for each file specified in the command line and
/// append them to ASTs.
int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
- /// \brief Returns the file manager used in the tool.
+ /// Returns the file manager used in the tool.
///
/// The file manager is shared between all translation units.
FileManager &getFiles() { return *Files; }
@@ -347,20 +371,22 @@ private:
llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFileSystem;
llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem;
llvm::IntrusiveRefCntPtr<FileManager> Files;
+
// Contains a list of pairs (<file name>, <file content>).
- std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
+ std::vector<std::pair<StringRef, StringRef>> MappedFileContents;
+
llvm::StringSet<> SeenWorkingDirectories;
ArgumentsAdjuster ArgsAdjuster;
- DiagnosticConsumer *DiagConsumer;
+ DiagnosticConsumer *DiagConsumer = nullptr;
};
template <typename T>
std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
class SimpleFrontendActionFactory : public FrontendActionFactory {
public:
- clang::FrontendAction *create() override { return new T; }
+ FrontendAction *create() override { return new T; }
};
return std::unique_ptr<FrontendActionFactory>(
@@ -374,36 +400,37 @@ inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
public:
explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
SourceFileCallbacks *Callbacks)
- : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
+ : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
- clang::FrontendAction *create() override {
+ FrontendAction *create() override {
return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
}
private:
- class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
+ class ConsumerFactoryAdaptor : public ASTFrontendAction {
public:
ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
SourceFileCallbacks *Callbacks)
- : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
+ : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
- std::unique_ptr<clang::ASTConsumer>
- CreateASTConsumer(clang::CompilerInstance &, StringRef) override {
+ std::unique_ptr<ASTConsumer>
+ CreateASTConsumer(CompilerInstance &, StringRef) override {
return ConsumerFactory->newASTConsumer();
}
protected:
bool BeginSourceFileAction(CompilerInstance &CI) override {
- if (!clang::ASTFrontendAction::BeginSourceFileAction(CI))
+ if (!ASTFrontendAction::BeginSourceFileAction(CI))
return false;
if (Callbacks)
return Callbacks->handleBeginSource(CI);
return true;
}
+
void EndSourceFileAction() override {
if (Callbacks)
Callbacks->handleEndSource();
- clang::ASTFrontendAction::EndSourceFileAction();
+ ASTFrontendAction::EndSourceFileAction();
}
private:
@@ -418,7 +445,7 @@ inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
}
-/// \brief Returns the absolute path of \c File, by prepending it with
+/// Returns the absolute path of \c File, by prepending it with
/// the current directory if \c File is not absolute.
///
/// Otherwise returns \c File.
@@ -432,7 +459,7 @@ inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
/// \param File Either an absolute or relative path.
std::string getAbsolutePath(StringRef File);
-/// \brief Changes CommandLine to contain implicit flags that would have been
+/// Changes CommandLine to contain implicit flags that would have been
/// defined had the compiler driver been invoked through the path InvokedAs.
///
/// For example, when called with \c InvokedAs set to `i686-linux-android-g++`,
@@ -455,12 +482,12 @@ std::string getAbsolutePath(StringRef File);
void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
StringRef InvokedAs);
-/// \brief Creates a \c CompilerInvocation.
-clang::CompilerInvocation *newInvocation(
- clang::DiagnosticsEngine *Diagnostics,
- const llvm::opt::ArgStringList &CC1Args);
+/// Creates a \c CompilerInvocation.
+CompilerInvocation *newInvocation(DiagnosticsEngine *Diagnostics,
+ const llvm::opt::ArgStringList &CC1Args);
+
+} // namespace tooling
-} // end namespace tooling
-} // end namespace clang
+} // namespace clang
#endif // LLVM_CLANG_TOOLING_TOOLING_H
diff --git a/include/clang/module.modulemap b/include/clang/module.modulemap
index 4097ad2dc7164..8d525c5ffbacd 100644
--- a/include/clang/module.modulemap
+++ b/include/clang/module.modulemap
@@ -42,6 +42,7 @@ module Clang_Basic {
textual header "Basic/BuiltinsX86_64.def"
textual header "Basic/BuiltinsXCore.def"
textual header "Basic/DiagnosticOptions.def"
+ textual header "Basic/Features.def"
textual header "Basic/LangOptions.def"
textual header "Basic/OpenCLExtensions.def"
textual header "Basic/OpenCLImageTypes.def"
@@ -153,3 +154,8 @@ module Clang_ToolingCore {
requires cplusplus
umbrella "Tooling/Core" module * { export * }
}
+
+module Clang_ToolingInclusions {
+ requires cplusplus
+ umbrella "Tooling/Inclusions" module * { export * }
+}